diff options
227 files changed, 10431 insertions, 4078 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index ee34ceb9ad5..325cfd1d6d9 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile | |||
@@ -32,10 +32,10 @@ PS_METHOD = $(prefer-db2x) | |||
32 | 32 | ||
33 | ### | 33 | ### |
34 | # The targets that may be used. | 34 | # The targets that may be used. |
35 | PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs media | 35 | PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs xmldoclinks |
36 | 36 | ||
37 | BOOKS := $(addprefix $(obj)/,$(DOCBOOKS)) | 37 | BOOKS := $(addprefix $(obj)/,$(DOCBOOKS)) |
38 | xmldocs: $(BOOKS) | 38 | xmldocs: $(BOOKS) xmldoclinks |
39 | sgmldocs: xmldocs | 39 | sgmldocs: xmldocs |
40 | 40 | ||
41 | PS := $(patsubst %.xml, %.ps, $(BOOKS)) | 41 | PS := $(patsubst %.xml, %.ps, $(BOOKS)) |
@@ -45,15 +45,24 @@ PDF := $(patsubst %.xml, %.pdf, $(BOOKS)) | |||
45 | pdfdocs: $(PDF) | 45 | pdfdocs: $(PDF) |
46 | 46 | ||
47 | HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS))) | 47 | HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS))) |
48 | htmldocs: media $(HTML) | 48 | htmldocs: $(HTML) |
49 | $(call build_main_index) | 49 | $(call build_main_index) |
50 | $(call build_images) | ||
50 | 51 | ||
51 | MAN := $(patsubst %.xml, %.9, $(BOOKS)) | 52 | MAN := $(patsubst %.xml, %.9, $(BOOKS)) |
52 | mandocs: $(MAN) | 53 | mandocs: $(MAN) |
53 | 54 | ||
54 | media: | 55 | build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \ |
55 | mkdir -p $(srctree)/Documentation/DocBook/media/ | 56 | cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/ |
56 | cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(srctree)/Documentation/DocBook/media/ | 57 | |
58 | xmldoclinks: | ||
59 | ifneq ($(objtree),$(srctree)) | ||
60 | for dep in dvb media-entities.tmpl media-indices.tmpl v4l; do \ | ||
61 | rm -f $(objtree)/Documentation/DocBook/$$dep \ | ||
62 | && ln -s $(srctree)/Documentation/DocBook/$$dep $(objtree)/Documentation/DocBook/ \ | ||
63 | || exit; \ | ||
64 | done | ||
65 | endif | ||
57 | 66 | ||
58 | installmandocs: mandocs | 67 | installmandocs: mandocs |
59 | mkdir -p /usr/local/man/man9/ | 68 | mkdir -p /usr/local/man/man9/ |
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl index bb5ab741220..c725cb852c5 100644 --- a/Documentation/DocBook/media-entities.tmpl +++ b/Documentation/DocBook/media-entities.tmpl | |||
@@ -23,6 +23,7 @@ | |||
23 | <!ENTITY VIDIOC-ENUMINPUT "<link linkend='vidioc-enuminput'><constant>VIDIOC_ENUMINPUT</constant></link>"> | 23 | <!ENTITY VIDIOC-ENUMINPUT "<link linkend='vidioc-enuminput'><constant>VIDIOC_ENUMINPUT</constant></link>"> |
24 | <!ENTITY VIDIOC-ENUMOUTPUT "<link linkend='vidioc-enumoutput'><constant>VIDIOC_ENUMOUTPUT</constant></link>"> | 24 | <!ENTITY VIDIOC-ENUMOUTPUT "<link linkend='vidioc-enumoutput'><constant>VIDIOC_ENUMOUTPUT</constant></link>"> |
25 | <!ENTITY VIDIOC-ENUMSTD "<link linkend='vidioc-enumstd'><constant>VIDIOC_ENUMSTD</constant></link>"> | 25 | <!ENTITY VIDIOC-ENUMSTD "<link linkend='vidioc-enumstd'><constant>VIDIOC_ENUMSTD</constant></link>"> |
26 | <!ENTITY VIDIOC-ENUM-DV-PRESETS "<link linkend='vidioc-enum-dv-presets'><constant>VIDIOC_ENUM_DV_PRESETS</constant></link>"> | ||
26 | <!ENTITY VIDIOC-ENUM-FMT "<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>"> | 27 | <!ENTITY VIDIOC-ENUM-FMT "<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>"> |
27 | <!ENTITY VIDIOC-ENUM-FRAMEINTERVALS "<link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>"> | 28 | <!ENTITY VIDIOC-ENUM-FRAMEINTERVALS "<link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>"> |
28 | <!ENTITY VIDIOC-ENUM-FRAMESIZES "<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>"> | 29 | <!ENTITY VIDIOC-ENUM-FRAMESIZES "<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>"> |
@@ -30,6 +31,8 @@ | |||
30 | <!ENTITY VIDIOC-G-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_G_AUDOUT</constant></link>"> | 31 | <!ENTITY VIDIOC-G-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_G_AUDOUT</constant></link>"> |
31 | <!ENTITY VIDIOC-G-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_G_CROP</constant></link>"> | 32 | <!ENTITY VIDIOC-G-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_G_CROP</constant></link>"> |
32 | <!ENTITY VIDIOC-G-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_G_CTRL</constant></link>"> | 33 | <!ENTITY VIDIOC-G-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_G_CTRL</constant></link>"> |
34 | <!ENTITY VIDIOC-G-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_G_DV_PRESET</constant></link>"> | ||
35 | <!ENTITY VIDIOC-G-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_G_DV_TIMINGS</constant></link>"> | ||
33 | <!ENTITY VIDIOC-G-ENC-INDEX "<link linkend='vidioc-g-enc-index'><constant>VIDIOC_G_ENC_INDEX</constant></link>"> | 36 | <!ENTITY VIDIOC-G-ENC-INDEX "<link linkend='vidioc-g-enc-index'><constant>VIDIOC_G_ENC_INDEX</constant></link>"> |
34 | <!ENTITY VIDIOC-G-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_G_EXT_CTRLS</constant></link>"> | 37 | <!ENTITY VIDIOC-G-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_G_EXT_CTRLS</constant></link>"> |
35 | <!ENTITY VIDIOC-G-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_G_FBUF</constant></link>"> | 38 | <!ENTITY VIDIOC-G-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_G_FBUF</constant></link>"> |
@@ -53,6 +56,7 @@ | |||
53 | <!ENTITY VIDIOC-QUERYCTRL "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYCTRL</constant></link>"> | 56 | <!ENTITY VIDIOC-QUERYCTRL "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYCTRL</constant></link>"> |
54 | <!ENTITY VIDIOC-QUERYMENU "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYMENU</constant></link>"> | 57 | <!ENTITY VIDIOC-QUERYMENU "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYMENU</constant></link>"> |
55 | <!ENTITY VIDIOC-QUERYSTD "<link linkend='vidioc-querystd'><constant>VIDIOC_QUERYSTD</constant></link>"> | 58 | <!ENTITY VIDIOC-QUERYSTD "<link linkend='vidioc-querystd'><constant>VIDIOC_QUERYSTD</constant></link>"> |
59 | <!ENTITY VIDIOC-QUERY-DV-PRESET "<link linkend='vidioc-query-dv-preset'><constant>VIDIOC_QUERY_DV_PRESET</constant></link>"> | ||
56 | <!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>"> | 60 | <!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>"> |
57 | <!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>"> | 61 | <!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>"> |
58 | <!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>"> | 62 | <!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>"> |
@@ -60,6 +64,8 @@ | |||
60 | <!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>"> | 64 | <!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>"> |
61 | <!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>"> | 65 | <!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>"> |
62 | <!ENTITY VIDIOC-S-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_S_CTRL</constant></link>"> | 66 | <!ENTITY VIDIOC-S-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_S_CTRL</constant></link>"> |
67 | <!ENTITY VIDIOC-S-DV-PRESET "<link linkend='vidioc-g-dv-preset'><constant>VIDIOC_S_DV_PRESET</constant></link>"> | ||
68 | <!ENTITY VIDIOC-S-DV-TIMINGS "<link linkend='vidioc-g-dv-timings'><constant>VIDIOC_S_DV_TIMINGS</constant></link>"> | ||
63 | <!ENTITY VIDIOC-S-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_S_EXT_CTRLS</constant></link>"> | 69 | <!ENTITY VIDIOC-S-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_S_EXT_CTRLS</constant></link>"> |
64 | <!ENTITY VIDIOC-S-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_S_FBUF</constant></link>"> | 70 | <!ENTITY VIDIOC-S-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_S_FBUF</constant></link>"> |
65 | <!ENTITY VIDIOC-S-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>"> | 71 | <!ENTITY VIDIOC-S-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>"> |
@@ -118,6 +124,7 @@ | |||
118 | <!-- Structures --> | 124 | <!-- Structures --> |
119 | <!ENTITY v4l2-audio "struct <link linkend='v4l2-audio'>v4l2_audio</link>"> | 125 | <!ENTITY v4l2-audio "struct <link linkend='v4l2-audio'>v4l2_audio</link>"> |
120 | <!ENTITY v4l2-audioout "struct <link linkend='v4l2-audioout'>v4l2_audioout</link>"> | 126 | <!ENTITY v4l2-audioout "struct <link linkend='v4l2-audioout'>v4l2_audioout</link>"> |
127 | <!ENTITY v4l2-bt-timings "struct <link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>"> | ||
121 | <!ENTITY v4l2-buffer "struct <link linkend='v4l2-buffer'>v4l2_buffer</link>"> | 128 | <!ENTITY v4l2-buffer "struct <link linkend='v4l2-buffer'>v4l2_buffer</link>"> |
122 | <!ENTITY v4l2-capability "struct <link linkend='v4l2-capability'>v4l2_capability</link>"> | 129 | <!ENTITY v4l2-capability "struct <link linkend='v4l2-capability'>v4l2_capability</link>"> |
123 | <!ENTITY v4l2-captureparm "struct <link linkend='v4l2-captureparm'>v4l2_captureparm</link>"> | 130 | <!ENTITY v4l2-captureparm "struct <link linkend='v4l2-captureparm'>v4l2_captureparm</link>"> |
@@ -128,6 +135,9 @@ | |||
128 | <!ENTITY v4l2-dbg-chip-ident "struct <link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link>"> | 135 | <!ENTITY v4l2-dbg-chip-ident "struct <link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link>"> |
129 | <!ENTITY v4l2-dbg-match "struct <link linkend='v4l2-dbg-match'>v4l2_dbg_match</link>"> | 136 | <!ENTITY v4l2-dbg-match "struct <link linkend='v4l2-dbg-match'>v4l2_dbg_match</link>"> |
130 | <!ENTITY v4l2-dbg-register "struct <link linkend='v4l2-dbg-register'>v4l2_dbg_register</link>"> | 137 | <!ENTITY v4l2-dbg-register "struct <link linkend='v4l2-dbg-register'>v4l2_dbg_register</link>"> |
138 | <!ENTITY v4l2-dv-enum-preset "struct <link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link>"> | ||
139 | <!ENTITY v4l2-dv-preset "struct <link linkend='v4l2-dv-preset'>v4l2_dv_preset</link>"> | ||
140 | <!ENTITY v4l2-dv-timings "struct <link linkend='v4l2-dv-timings'>v4l2_dv_timings</link>"> | ||
131 | <!ENTITY v4l2-enc-idx "struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>"> | 141 | <!ENTITY v4l2-enc-idx "struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>"> |
132 | <!ENTITY v4l2-enc-idx-entry "struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>"> | 142 | <!ENTITY v4l2-enc-idx-entry "struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>"> |
133 | <!ENTITY v4l2-encoder-cmd "struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>"> | 143 | <!ENTITY v4l2-encoder-cmd "struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>"> |
@@ -243,6 +253,10 @@ | |||
243 | <!ENTITY sub-enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml"> | 253 | <!ENTITY sub-enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml"> |
244 | <!ENTITY sub-enuminput SYSTEM "v4l/vidioc-enuminput.xml"> | 254 | <!ENTITY sub-enuminput SYSTEM "v4l/vidioc-enuminput.xml"> |
245 | <!ENTITY sub-enumoutput SYSTEM "v4l/vidioc-enumoutput.xml"> | 255 | <!ENTITY sub-enumoutput SYSTEM "v4l/vidioc-enumoutput.xml"> |
256 | <!ENTITY sub-enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml"> | ||
257 | <!ENTITY sub-g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml"> | ||
258 | <!ENTITY sub-query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml"> | ||
259 | <!ENTITY sub-g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml"> | ||
246 | <!ENTITY sub-enumstd SYSTEM "v4l/vidioc-enumstd.xml"> | 260 | <!ENTITY sub-enumstd SYSTEM "v4l/vidioc-enumstd.xml"> |
247 | <!ENTITY sub-g-audio SYSTEM "v4l/vidioc-g-audio.xml"> | 261 | <!ENTITY sub-g-audio SYSTEM "v4l/vidioc-g-audio.xml"> |
248 | <!ENTITY sub-g-audioout SYSTEM "v4l/vidioc-g-audioout.xml"> | 262 | <!ENTITY sub-g-audioout SYSTEM "v4l/vidioc-g-audioout.xml"> |
@@ -333,6 +347,10 @@ | |||
333 | <!ENTITY enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml"> | 347 | <!ENTITY enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml"> |
334 | <!ENTITY enuminput SYSTEM "v4l/vidioc-enuminput.xml"> | 348 | <!ENTITY enuminput SYSTEM "v4l/vidioc-enuminput.xml"> |
335 | <!ENTITY enumoutput SYSTEM "v4l/vidioc-enumoutput.xml"> | 349 | <!ENTITY enumoutput SYSTEM "v4l/vidioc-enumoutput.xml"> |
350 | <!ENTITY enum-dv-presets SYSTEM "v4l/vidioc-enum-dv-presets.xml"> | ||
351 | <!ENTITY g-dv-preset SYSTEM "v4l/vidioc-g-dv-preset.xml"> | ||
352 | <!ENTITY query-dv-preset SYSTEM "v4l/vidioc-query-dv-preset.xml"> | ||
353 | <!ENTITY g-dv-timings SYSTEM "v4l/vidioc-g-dv-timings.xml"> | ||
336 | <!ENTITY enumstd SYSTEM "v4l/vidioc-enumstd.xml"> | 354 | <!ENTITY enumstd SYSTEM "v4l/vidioc-enumstd.xml"> |
337 | <!ENTITY g-audio SYSTEM "v4l/vidioc-g-audio.xml"> | 355 | <!ENTITY g-audio SYSTEM "v4l/vidioc-g-audio.xml"> |
338 | <!ENTITY g-audioout SYSTEM "v4l/vidioc-g-audioout.xml"> | 356 | <!ENTITY g-audioout SYSTEM "v4l/vidioc-g-audioout.xml"> |
diff --git a/Documentation/DocBook/media-indices.tmpl b/Documentation/DocBook/media-indices.tmpl index 9e30a236d74..78d6031de00 100644 --- a/Documentation/DocBook/media-indices.tmpl +++ b/Documentation/DocBook/media-indices.tmpl | |||
@@ -36,6 +36,7 @@ | |||
36 | <indexentry><primaryie>enum <link linkend='v4l2-preemphasis'>v4l2_preemphasis</link></primaryie></indexentry> | 36 | <indexentry><primaryie>enum <link linkend='v4l2-preemphasis'>v4l2_preemphasis</link></primaryie></indexentry> |
37 | <indexentry><primaryie>struct <link linkend='v4l2-audio'>v4l2_audio</link></primaryie></indexentry> | 37 | <indexentry><primaryie>struct <link linkend='v4l2-audio'>v4l2_audio</link></primaryie></indexentry> |
38 | <indexentry><primaryie>struct <link linkend='v4l2-audioout'>v4l2_audioout</link></primaryie></indexentry> | 38 | <indexentry><primaryie>struct <link linkend='v4l2-audioout'>v4l2_audioout</link></primaryie></indexentry> |
39 | <indexentry><primaryie>struct <link linkend='v4l2-bt-timings'>v4l2_bt_timings</link></primaryie></indexentry> | ||
39 | <indexentry><primaryie>struct <link linkend='v4l2-buffer'>v4l2_buffer</link></primaryie></indexentry> | 40 | <indexentry><primaryie>struct <link linkend='v4l2-buffer'>v4l2_buffer</link></primaryie></indexentry> |
40 | <indexentry><primaryie>struct <link linkend='v4l2-capability'>v4l2_capability</link></primaryie></indexentry> | 41 | <indexentry><primaryie>struct <link linkend='v4l2-capability'>v4l2_capability</link></primaryie></indexentry> |
41 | <indexentry><primaryie>struct <link linkend='v4l2-captureparm'>v4l2_captureparm</link></primaryie></indexentry> | 42 | <indexentry><primaryie>struct <link linkend='v4l2-captureparm'>v4l2_captureparm</link></primaryie></indexentry> |
@@ -46,6 +47,9 @@ | |||
46 | <indexentry><primaryie>struct <link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link></primaryie></indexentry> | 47 | <indexentry><primaryie>struct <link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link></primaryie></indexentry> |
47 | <indexentry><primaryie>struct <link linkend='v4l2-dbg-match'>v4l2_dbg_match</link></primaryie></indexentry> | 48 | <indexentry><primaryie>struct <link linkend='v4l2-dbg-match'>v4l2_dbg_match</link></primaryie></indexentry> |
48 | <indexentry><primaryie>struct <link linkend='v4l2-dbg-register'>v4l2_dbg_register</link></primaryie></indexentry> | 49 | <indexentry><primaryie>struct <link linkend='v4l2-dbg-register'>v4l2_dbg_register</link></primaryie></indexentry> |
50 | <indexentry><primaryie>struct <link linkend='v4l2-dv-enum-preset'>v4l2_dv_enum_preset</link></primaryie></indexentry> | ||
51 | <indexentry><primaryie>struct <link linkend='v4l2-dv-preset'>v4l2_dv_preset</link></primaryie></indexentry> | ||
52 | <indexentry><primaryie>struct <link linkend='v4l2-dv-timings'>v4l2_dv_timings</link></primaryie></indexentry> | ||
49 | <indexentry><primaryie>struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link></primaryie></indexentry> | 53 | <indexentry><primaryie>struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link></primaryie></indexentry> |
50 | <indexentry><primaryie>struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link></primaryie></indexentry> | 54 | <indexentry><primaryie>struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link></primaryie></indexentry> |
51 | <indexentry><primaryie>struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link></primaryie></indexentry> | 55 | <indexentry><primaryie>struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link></primaryie></indexentry> |
diff --git a/Documentation/DocBook/v4l/common.xml b/Documentation/DocBook/v4l/common.xml index b1a81d246d5..c65f0ac9b6e 100644 --- a/Documentation/DocBook/v4l/common.xml +++ b/Documentation/DocBook/v4l/common.xml | |||
@@ -716,6 +716,41 @@ if (-1 == ioctl (fd, &VIDIOC-S-STD;, &std_id)) { | |||
716 | } | 716 | } |
717 | </programlisting> | 717 | </programlisting> |
718 | </example> | 718 | </example> |
719 | <section id="dv-timings"> | ||
720 | <title>Digital Video (DV) Timings</title> | ||
721 | <para> | ||
722 | The video standards discussed so far has been dealing with Analog TV and the | ||
723 | corresponding video timings. Today there are many more different hardware interfaces | ||
724 | such as High Definition TV interfaces (HDMI), VGA, DVI connectors etc., that carry | ||
725 | video signals and there is a need to extend the API to select the video timings | ||
726 | for these interfaces. Since it is not possible to extend the &v4l2-std-id; due to | ||
727 | the limited bits available, a new set of IOCTLs is added to set/get video timings at | ||
728 | the input and output: </para><itemizedlist> | ||
729 | <listitem> | ||
730 | <para>DV Presets: Digital Video (DV) presets. These are IDs representing a | ||
731 | video timing at the input/output. Presets are pre-defined timings implemented | ||
732 | by the hardware according to video standards. A __u32 data type is used to represent | ||
733 | a preset unlike the bit mask that is used in &v4l2-std-id; allowing future extensions | ||
734 | to support as many different presets as needed.</para> | ||
735 | </listitem> | ||
736 | <listitem> | ||
737 | <para>Custom DV Timings: This will allow applications to define more detailed | ||
738 | custom video timings for the interface. This includes parameters such as width, height, | ||
739 | polarities, frontporch, backporch etc. | ||
740 | </para> | ||
741 | </listitem> | ||
742 | </itemizedlist> | ||
743 | <para>To enumerate and query the attributes of DV presets supported by a device, | ||
744 | applications use the &VIDIOC-ENUM-DV-PRESETS; ioctl. To get the current DV preset, | ||
745 | applications use the &VIDIOC-G-DV-PRESET; ioctl and to set a preset they use the | ||
746 | &VIDIOC-S-DV-PRESET; ioctl.</para> | ||
747 | <para>To set custom DV timings for the device, applications use the | ||
748 | &VIDIOC-S-DV-TIMINGS; ioctl and to get current custom DV timings they use the | ||
749 | &VIDIOC-G-DV-TIMINGS; ioctl.</para> | ||
750 | <para>Applications can make use of the <xref linkend="input-capabilities" /> and | ||
751 | <xref linkend="output-capabilities"/> flags to decide what ioctls are available to set the | ||
752 | video timings for the device.</para> | ||
753 | </section> | ||
719 | </section> | 754 | </section> |
720 | 755 | ||
721 | &sub-controls; | 756 | &sub-controls; |
diff --git a/Documentation/DocBook/v4l/compat.xml b/Documentation/DocBook/v4l/compat.xml index 4d1902a54d6..b9dbdf9e6d2 100644 --- a/Documentation/DocBook/v4l/compat.xml +++ b/Documentation/DocBook/v4l/compat.xml | |||
@@ -2291,8 +2291,8 @@ was renamed to <structname id="v4l2-chip-ident-old">v4l2_chip_ident_old</structn | |||
2291 | <listitem> | 2291 | <listitem> |
2292 | <para>New control <constant>V4L2_CID_COLORFX</constant> was added.</para> | 2292 | <para>New control <constant>V4L2_CID_COLORFX</constant> was added.</para> |
2293 | </listitem> | 2293 | </listitem> |
2294 | </orderedlist> | 2294 | </orderedlist> |
2295 | </section> | 2295 | </section> |
2296 | <section> | 2296 | <section> |
2297 | <title>V4L2 in Linux 2.6.32</title> | 2297 | <title>V4L2 in Linux 2.6.32</title> |
2298 | <orderedlist> | 2298 | <orderedlist> |
@@ -2322,8 +2322,16 @@ more information.</para> | |||
2322 | <listitem> | 2322 | <listitem> |
2323 | <para>Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.</para> | 2323 | <para>Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.</para> |
2324 | </listitem> | 2324 | </listitem> |
2325 | </orderedlist> | 2325 | </orderedlist> |
2326 | </section> | 2326 | </section> |
2327 | <section> | ||
2328 | <title>V4L2 in Linux 2.6.33</title> | ||
2329 | <orderedlist> | ||
2330 | <listitem> | ||
2331 | <para>Added support for Digital Video timings in order to support HDTV receivers and transmitters.</para> | ||
2332 | </listitem> | ||
2333 | </orderedlist> | ||
2334 | </section> | ||
2327 | </section> | 2335 | </section> |
2328 | 2336 | ||
2329 | <section id="other"> | 2337 | <section id="other"> |
diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml index 937b4157a5d..060105af49e 100644 --- a/Documentation/DocBook/v4l/v4l2.xml +++ b/Documentation/DocBook/v4l/v4l2.xml | |||
@@ -74,6 +74,17 @@ Remote Controller chapter.</contrib> | |||
74 | </address> | 74 | </address> |
75 | </affiliation> | 75 | </affiliation> |
76 | </author> | 76 | </author> |
77 | |||
78 | <author> | ||
79 | <firstname>Muralidharan</firstname> | ||
80 | <surname>Karicheri</surname> | ||
81 | <contrib>Documented the Digital Video timings API.</contrib> | ||
82 | <affiliation> | ||
83 | <address> | ||
84 | <email>m-karicheri2@ti.com</email> | ||
85 | </address> | ||
86 | </affiliation> | ||
87 | </author> | ||
77 | </authorgroup> | 88 | </authorgroup> |
78 | 89 | ||
79 | <copyright> | 90 | <copyright> |
@@ -89,7 +100,7 @@ Remote Controller chapter.</contrib> | |||
89 | <year>2008</year> | 100 | <year>2008</year> |
90 | <year>2009</year> | 101 | <year>2009</year> |
91 | <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin | 102 | <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin |
92 | Rubli, Andy Walls, Mauro Carvalho Chehab</holder> | 103 | Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder> |
93 | </copyright> | 104 | </copyright> |
94 | <legalnotice> | 105 | <legalnotice> |
95 | <para>Except when explicitly stated as GPL, programming examples within | 106 | <para>Except when explicitly stated as GPL, programming examples within |
@@ -103,6 +114,13 @@ structs, ioctls) must be noted in more detail in the history chapter | |||
103 | applications. --> | 114 | applications. --> |
104 | 115 | ||
105 | <revision> | 116 | <revision> |
117 | <revnumber>2.6.33</revnumber> | ||
118 | <date>2009-12-03</date> | ||
119 | <authorinitials>mk</authorinitials> | ||
120 | <revremark>Added documentation for the Digital Video timings API.</revremark> | ||
121 | </revision> | ||
122 | |||
123 | <revision> | ||
106 | <revnumber>2.6.32</revnumber> | 124 | <revnumber>2.6.32</revnumber> |
107 | <date>2009-08-31</date> | 125 | <date>2009-08-31</date> |
108 | <authorinitials>mcc</authorinitials> | 126 | <authorinitials>mcc</authorinitials> |
@@ -355,7 +373,7 @@ and discussions on the V4L mailing list.</revremark> | |||
355 | </partinfo> | 373 | </partinfo> |
356 | 374 | ||
357 | <title>Video for Linux Two API Specification</title> | 375 | <title>Video for Linux Two API Specification</title> |
358 | <subtitle>Revision 2.6.32</subtitle> | 376 | <subtitle>Revision 2.6.33</subtitle> |
359 | 377 | ||
360 | <chapter id="common"> | 378 | <chapter id="common"> |
361 | &sub-common; | 379 | &sub-common; |
@@ -411,6 +429,7 @@ and discussions on the V4L mailing list.</revremark> | |||
411 | &sub-encoder-cmd; | 429 | &sub-encoder-cmd; |
412 | &sub-enumaudio; | 430 | &sub-enumaudio; |
413 | &sub-enumaudioout; | 431 | &sub-enumaudioout; |
432 | &sub-enum-dv-presets; | ||
414 | &sub-enum-fmt; | 433 | &sub-enum-fmt; |
415 | &sub-enum-framesizes; | 434 | &sub-enum-framesizes; |
416 | &sub-enum-frameintervals; | 435 | &sub-enum-frameintervals; |
@@ -421,6 +440,8 @@ and discussions on the V4L mailing list.</revremark> | |||
421 | &sub-g-audioout; | 440 | &sub-g-audioout; |
422 | &sub-g-crop; | 441 | &sub-g-crop; |
423 | &sub-g-ctrl; | 442 | &sub-g-ctrl; |
443 | &sub-g-dv-preset; | ||
444 | &sub-g-dv-timings; | ||
424 | &sub-g-enc-index; | 445 | &sub-g-enc-index; |
425 | &sub-g-ext-ctrls; | 446 | &sub-g-ext-ctrls; |
426 | &sub-g-fbuf; | 447 | &sub-g-fbuf; |
@@ -441,6 +462,7 @@ and discussions on the V4L mailing list.</revremark> | |||
441 | &sub-querybuf; | 462 | &sub-querybuf; |
442 | &sub-querycap; | 463 | &sub-querycap; |
443 | &sub-queryctrl; | 464 | &sub-queryctrl; |
465 | &sub-query-dv-preset; | ||
444 | &sub-querystd; | 466 | &sub-querystd; |
445 | &sub-reqbufs; | 467 | &sub-reqbufs; |
446 | &sub-s-hw-freq-seek; | 468 | &sub-s-hw-freq-seek; |
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml index 3e282ed9f59..06832594065 100644 --- a/Documentation/DocBook/v4l/videodev2.h.xml +++ b/Documentation/DocBook/v4l/videodev2.h.xml | |||
@@ -734,6 +734,99 @@ struct <link linkend="v4l2-standard">v4l2_standard</link> { | |||
734 | }; | 734 | }; |
735 | 735 | ||
736 | /* | 736 | /* |
737 | * V I D E O T I M I N G S D V P R E S E T | ||
738 | */ | ||
739 | struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link> { | ||
740 | __u32 preset; | ||
741 | __u32 reserved[4]; | ||
742 | }; | ||
743 | |||
744 | /* | ||
745 | * D V P R E S E T S E N U M E R A T I O N | ||
746 | */ | ||
747 | struct <link linkend="v4l2-dv-enum-preset">v4l2_dv_enum_preset</link> { | ||
748 | __u32 index; | ||
749 | __u32 preset; | ||
750 | __u8 name[32]; /* Name of the preset timing */ | ||
751 | __u32 width; | ||
752 | __u32 height; | ||
753 | __u32 reserved[4]; | ||
754 | }; | ||
755 | |||
756 | /* | ||
757 | * D V P R E S E T V A L U E S | ||
758 | */ | ||
759 | #define V4L2_DV_INVALID 0 | ||
760 | #define V4L2_DV_480P59_94 1 /* BT.1362 */ | ||
761 | #define V4L2_DV_576P50 2 /* BT.1362 */ | ||
762 | #define V4L2_DV_720P24 3 /* SMPTE 296M */ | ||
763 | #define V4L2_DV_720P25 4 /* SMPTE 296M */ | ||
764 | #define V4L2_DV_720P30 5 /* SMPTE 296M */ | ||
765 | #define V4L2_DV_720P50 6 /* SMPTE 296M */ | ||
766 | #define V4L2_DV_720P59_94 7 /* SMPTE 274M */ | ||
767 | #define V4L2_DV_720P60 8 /* SMPTE 274M/296M */ | ||
768 | #define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */ | ||
769 | #define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */ | ||
770 | #define V4L2_DV_1080I25 11 /* BT.1120 */ | ||
771 | #define V4L2_DV_1080I50 12 /* SMPTE 296M */ | ||
772 | #define V4L2_DV_1080I60 13 /* SMPTE 296M */ | ||
773 | #define V4L2_DV_1080P24 14 /* SMPTE 296M */ | ||
774 | #define V4L2_DV_1080P25 15 /* SMPTE 296M */ | ||
775 | #define V4L2_DV_1080P30 16 /* SMPTE 296M */ | ||
776 | #define V4L2_DV_1080P50 17 /* BT.1120 */ | ||
777 | #define V4L2_DV_1080P60 18 /* BT.1120 */ | ||
778 | |||
779 | /* | ||
780 | * D V B T T I M I N G S | ||
781 | */ | ||
782 | |||
783 | /* BT.656/BT.1120 timing data */ | ||
784 | struct <link linkend="v4l2-bt-timings">v4l2_bt_timings</link> { | ||
785 | __u32 width; /* width in pixels */ | ||
786 | __u32 height; /* height in lines */ | ||
787 | __u32 interlaced; /* Interlaced or progressive */ | ||
788 | __u32 polarities; /* Positive or negative polarity */ | ||
789 | __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ | ||
790 | __u32 hfrontporch; /* Horizpontal front porch in pixels */ | ||
791 | __u32 hsync; /* Horizontal Sync length in pixels */ | ||
792 | __u32 hbackporch; /* Horizontal back porch in pixels */ | ||
793 | __u32 vfrontporch; /* Vertical front porch in pixels */ | ||
794 | __u32 vsync; /* Vertical Sync length in lines */ | ||
795 | __u32 vbackporch; /* Vertical back porch in lines */ | ||
796 | __u32 il_vfrontporch; /* Vertical front porch for bottom field of | ||
797 | * interlaced field formats | ||
798 | */ | ||
799 | __u32 il_vsync; /* Vertical sync length for bottom field of | ||
800 | * interlaced field formats | ||
801 | */ | ||
802 | __u32 il_vbackporch; /* Vertical back porch for bottom field of | ||
803 | * interlaced field formats | ||
804 | */ | ||
805 | __u32 reserved[16]; | ||
806 | } __attribute__ ((packed)); | ||
807 | |||
808 | /* Interlaced or progressive format */ | ||
809 | #define V4L2_DV_PROGRESSIVE 0 | ||
810 | #define V4L2_DV_INTERLACED 1 | ||
811 | |||
812 | /* Polarities. If bit is not set, it is assumed to be negative polarity */ | ||
813 | #define V4L2_DV_VSYNC_POS_POL 0x00000001 | ||
814 | #define V4L2_DV_HSYNC_POS_POL 0x00000002 | ||
815 | |||
816 | |||
817 | /* DV timings */ | ||
818 | struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link> { | ||
819 | __u32 type; | ||
820 | union { | ||
821 | struct <link linkend="v4l2-bt-timings">v4l2_bt_timings</link> bt; | ||
822 | __u32 reserved[32]; | ||
823 | }; | ||
824 | } __attribute__ ((packed)); | ||
825 | |||
826 | /* Values for the type field */ | ||
827 | #define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ | ||
828 | |||
829 | /* | ||
737 | * V I D E O I N P U T S | 830 | * V I D E O I N P U T S |
738 | */ | 831 | */ |
739 | struct <link linkend="v4l2-input">v4l2_input</link> { | 832 | struct <link linkend="v4l2-input">v4l2_input</link> { |
@@ -744,7 +837,8 @@ struct <link linkend="v4l2-input">v4l2_input</link> { | |||
744 | __u32 tuner; /* Associated tuner */ | 837 | __u32 tuner; /* Associated tuner */ |
745 | v4l2_std_id std; | 838 | v4l2_std_id std; |
746 | __u32 status; | 839 | __u32 status; |
747 | __u32 reserved[4]; | 840 | __u32 capabilities; |
841 | __u32 reserved[3]; | ||
748 | }; | 842 | }; |
749 | 843 | ||
750 | /* Values for the 'type' field */ | 844 | /* Values for the 'type' field */ |
@@ -775,6 +869,11 @@ struct <link linkend="v4l2-input">v4l2_input</link> { | |||
775 | #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ | 869 | #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ |
776 | #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ | 870 | #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ |
777 | 871 | ||
872 | /* capabilities flags */ | ||
873 | #define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ | ||
874 | #define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ | ||
875 | #define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ | ||
876 | |||
778 | /* | 877 | /* |
779 | * V I D E O O U T P U T S | 878 | * V I D E O O U T P U T S |
780 | */ | 879 | */ |
@@ -785,13 +884,19 @@ struct <link linkend="v4l2-output">v4l2_output</link> { | |||
785 | __u32 audioset; /* Associated audios (bitfield) */ | 884 | __u32 audioset; /* Associated audios (bitfield) */ |
786 | __u32 modulator; /* Associated modulator */ | 885 | __u32 modulator; /* Associated modulator */ |
787 | v4l2_std_id std; | 886 | v4l2_std_id std; |
788 | __u32 reserved[4]; | 887 | __u32 capabilities; |
888 | __u32 reserved[3]; | ||
789 | }; | 889 | }; |
790 | /* Values for the 'type' field */ | 890 | /* Values for the 'type' field */ |
791 | #define V4L2_OUTPUT_TYPE_MODULATOR 1 | 891 | #define V4L2_OUTPUT_TYPE_MODULATOR 1 |
792 | #define V4L2_OUTPUT_TYPE_ANALOG 2 | 892 | #define V4L2_OUTPUT_TYPE_ANALOG 2 |
793 | #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 | 893 | #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 |
794 | 894 | ||
895 | /* capabilities flags */ | ||
896 | #define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ | ||
897 | #define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ | ||
898 | #define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ | ||
899 | |||
795 | /* | 900 | /* |
796 | * C O N T R O L S | 901 | * C O N T R O L S |
797 | */ | 902 | */ |
@@ -1626,6 +1731,13 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> { | |||
1626 | #endif | 1731 | #endif |
1627 | 1732 | ||
1628 | #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link>) | 1733 | #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link>) |
1734 | #define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct <link linkend="v4l2-dv-enum-preset">v4l2_dv_enum_preset</link>) | ||
1735 | #define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>) | ||
1736 | #define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>) | ||
1737 | #define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct <link linkend="v4l2-dv-preset">v4l2_dv_preset</link>) | ||
1738 | #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>) | ||
1739 | #define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct <link linkend="v4l2-dv-timings">v4l2_dv_timings</link>) | ||
1740 | |||
1629 | /* Reminder: when adding new ioctls please add support for them to | 1741 | /* Reminder: when adding new ioctls please add support for them to |
1630 | drivers/media/video/v4l2-compat-ioctl32.c as well! */ | 1742 | drivers/media/video/v4l2-compat-ioctl32.c as well! */ |
1631 | 1743 | ||
diff --git a/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml b/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml new file mode 100644 index 00000000000..1d31427edd1 --- /dev/null +++ b/Documentation/DocBook/v4l/vidioc-enum-dv-presets.xml | |||
@@ -0,0 +1,238 @@ | |||
1 | <refentry id="vidioc-enum-dv-presets"> | ||
2 | <refmeta> | ||
3 | <refentrytitle>ioctl VIDIOC_ENUM_DV_PRESETS</refentrytitle> | ||
4 | &manvol; | ||
5 | </refmeta> | ||
6 | |||
7 | <refnamediv> | ||
8 | <refname>VIDIOC_ENUM_DV_PRESETS</refname> | ||
9 | <refpurpose>Enumerate supported Digital Video presets</refpurpose> | ||
10 | </refnamediv> | ||
11 | |||
12 | <refsynopsisdiv> | ||
13 | <funcsynopsis> | ||
14 | <funcprototype> | ||
15 | <funcdef>int <function>ioctl</function></funcdef> | ||
16 | <paramdef>int <parameter>fd</parameter></paramdef> | ||
17 | <paramdef>int <parameter>request</parameter></paramdef> | ||
18 | <paramdef>struct v4l2_dv_enum_preset *<parameter>argp</parameter></paramdef> | ||
19 | </funcprototype> | ||
20 | </funcsynopsis> | ||
21 | </refsynopsisdiv> | ||
22 | |||
23 | <refsect1> | ||
24 | <title>Arguments</title> | ||
25 | |||
26 | <variablelist> | ||
27 | <varlistentry> | ||
28 | <term><parameter>fd</parameter></term> | ||
29 | <listitem> | ||
30 | <para>&fd;</para> | ||
31 | </listitem> | ||
32 | </varlistentry> | ||
33 | <varlistentry> | ||
34 | <term><parameter>request</parameter></term> | ||
35 | <listitem> | ||
36 | <para>VIDIOC_ENUM_DV_PRESETS</para> | ||
37 | </listitem> | ||
38 | </varlistentry> | ||
39 | <varlistentry> | ||
40 | <term><parameter>argp</parameter></term> | ||
41 | <listitem> | ||
42 | <para></para> | ||
43 | </listitem> | ||
44 | </varlistentry> | ||
45 | </variablelist> | ||
46 | </refsect1> | ||
47 | |||
48 | <refsect1> | ||
49 | <title>Description</title> | ||
50 | |||
51 | <para>To query the attributes of a DV preset, applications initialize the | ||
52 | <structfield>index</structfield> field and zero the reserved array of &v4l2-dv-enum-preset; | ||
53 | and call the <constant>VIDIOC_ENUM_DV_PRESETS</constant> ioctl with a pointer to this | ||
54 | structure. Drivers fill the rest of the structure or return an | ||
55 | &EINVAL; when the index is out of bounds. To enumerate all DV Presets supported, | ||
56 | applications shall begin at index zero, incrementing by one until the | ||
57 | driver returns <errorcode>EINVAL</errorcode>. Drivers may enumerate a | ||
58 | different set of DV presets after switching the video input or | ||
59 | output.</para> | ||
60 | |||
61 | <table pgwide="1" frame="none" id="v4l2-dv-enum-preset"> | ||
62 | <title>struct <structname>v4l2_dv_enum_presets</structname></title> | ||
63 | <tgroup cols="3"> | ||
64 | &cs-str; | ||
65 | <tbody valign="top"> | ||
66 | <row> | ||
67 | <entry>__u32</entry> | ||
68 | <entry><structfield>index</structfield></entry> | ||
69 | <entry>Number of the DV preset, set by the | ||
70 | application.</entry> | ||
71 | </row> | ||
72 | <row> | ||
73 | <entry>__u32</entry> | ||
74 | <entry><structfield>preset</structfield></entry> | ||
75 | <entry>This field identifies one of the DV preset values listed in <xref linkend="v4l2-dv-presets-vals"/>.</entry> | ||
76 | </row> | ||
77 | <row> | ||
78 | <entry>__u8</entry> | ||
79 | <entry><structfield>name</structfield>[24]</entry> | ||
80 | <entry>Name of the preset, a NUL-terminated ASCII string, for example: "720P-60", "1080I-60". This information is | ||
81 | intended for the user.</entry> | ||
82 | </row> | ||
83 | <row> | ||
84 | <entry>__u32</entry> | ||
85 | <entry><structfield>width</structfield></entry> | ||
86 | <entry>Width of the active video in pixels for the DV preset.</entry> | ||
87 | </row> | ||
88 | <row> | ||
89 | <entry>__u32</entry> | ||
90 | <entry><structfield>height</structfield></entry> | ||
91 | <entry>Height of the active video in lines for the DV preset.</entry> | ||
92 | </row> | ||
93 | <row> | ||
94 | <entry>__u32</entry> | ||
95 | <entry><structfield>reserved</structfield>[4]</entry> | ||
96 | <entry>Reserved for future extensions. Drivers must set the array to zero.</entry> | ||
97 | </row> | ||
98 | </tbody> | ||
99 | </tgroup> | ||
100 | </table> | ||
101 | |||
102 | <table pgwide="1" frame="none" id="v4l2-dv-presets-vals"> | ||
103 | <title>struct <structname>DV Presets</structname></title> | ||
104 | <tgroup cols="3"> | ||
105 | &cs-str; | ||
106 | <tbody valign="top"> | ||
107 | <row> | ||
108 | <entry>Preset</entry> | ||
109 | <entry>Preset value</entry> | ||
110 | <entry>Description</entry> | ||
111 | </row> | ||
112 | <row> | ||
113 | <entry></entry> | ||
114 | <entry></entry> | ||
115 | <entry></entry> | ||
116 | </row> | ||
117 | <row> | ||
118 | <entry>V4L2_DV_INVALID</entry> | ||
119 | <entry>0</entry> | ||
120 | <entry>Invalid preset value.</entry> | ||
121 | </row> | ||
122 | <row> | ||
123 | <entry>V4L2_DV_480P59_94</entry> | ||
124 | <entry>1</entry> | ||
125 | <entry>720x480 progressive video at 59.94 fps as per BT.1362.</entry> | ||
126 | </row> | ||
127 | <row> | ||
128 | <entry>V4L2_DV_576P50</entry> | ||
129 | <entry>2</entry> | ||
130 | <entry>720x576 progressive video at 50 fps as per BT.1362.</entry> | ||
131 | </row> | ||
132 | <row> | ||
133 | <entry>V4L2_DV_720P24</entry> | ||
134 | <entry>3</entry> | ||
135 | <entry>1280x720 progressive video at 24 fps as per SMPTE 296M.</entry> | ||
136 | </row> | ||
137 | <row> | ||
138 | <entry>V4L2_DV_720P25</entry> | ||
139 | <entry>4</entry> | ||
140 | <entry>1280x720 progressive video at 25 fps as per SMPTE 296M.</entry> | ||
141 | </row> | ||
142 | <row> | ||
143 | <entry>V4L2_DV_720P30</entry> | ||
144 | <entry>5</entry> | ||
145 | <entry>1280x720 progressive video at 30 fps as per SMPTE 296M.</entry> | ||
146 | </row> | ||
147 | <row> | ||
148 | <entry>V4L2_DV_720P50</entry> | ||
149 | <entry>6</entry> | ||
150 | <entry>1280x720 progressive video at 50 fps as per SMPTE 296M.</entry> | ||
151 | </row> | ||
152 | <row> | ||
153 | <entry>V4L2_DV_720P59_94</entry> | ||
154 | <entry>7</entry> | ||
155 | <entry>1280x720 progressive video at 59.94 fps as per SMPTE 274M.</entry> | ||
156 | </row> | ||
157 | <row> | ||
158 | <entry>V4L2_DV_720P60</entry> | ||
159 | <entry>8</entry> | ||
160 | <entry>1280x720 progressive video at 60 fps as per SMPTE 274M/296M.</entry> | ||
161 | </row> | ||
162 | <row> | ||
163 | <entry>V4L2_DV_1080I29_97</entry> | ||
164 | <entry>9</entry> | ||
165 | <entry>1920x1080 interlaced video at 29.97 fps as per BT.1120/SMPTE 274M.</entry> | ||
166 | </row> | ||
167 | <row> | ||
168 | <entry>V4L2_DV_1080I30</entry> | ||
169 | <entry>10</entry> | ||
170 | <entry>1920x1080 interlaced video at 30 fps as per BT.1120/SMPTE 274M.</entry> | ||
171 | </row> | ||
172 | <row> | ||
173 | <entry>V4L2_DV_1080I25</entry> | ||
174 | <entry>11</entry> | ||
175 | <entry>1920x1080 interlaced video at 25 fps as per BT.1120.</entry> | ||
176 | </row> | ||
177 | <row> | ||
178 | <entry>V4L2_DV_1080I50</entry> | ||
179 | <entry>12</entry> | ||
180 | <entry>1920x1080 interlaced video at 50 fps as per SMPTE 296M.</entry> | ||
181 | </row> | ||
182 | <row> | ||
183 | <entry>V4L2_DV_1080I60</entry> | ||
184 | <entry>13</entry> | ||
185 | <entry>1920x1080 interlaced video at 60 fps as per SMPTE 296M.</entry> | ||
186 | </row> | ||
187 | <row> | ||
188 | <entry>V4L2_DV_1080P24</entry> | ||
189 | <entry>14</entry> | ||
190 | <entry>1920x1080 progressive video at 24 fps as per SMPTE 296M.</entry> | ||
191 | </row> | ||
192 | <row> | ||
193 | <entry>V4L2_DV_1080P25</entry> | ||
194 | <entry>15</entry> | ||
195 | <entry>1920x1080 progressive video at 25 fps as per SMPTE 296M.</entry> | ||
196 | </row> | ||
197 | <row> | ||
198 | <entry>V4L2_DV_1080P30</entry> | ||
199 | <entry>16</entry> | ||
200 | <entry>1920x1080 progressive video at 30 fps as per SMPTE 296M.</entry> | ||
201 | </row> | ||
202 | <row> | ||
203 | <entry>V4L2_DV_1080P50</entry> | ||
204 | <entry>17</entry> | ||
205 | <entry>1920x1080 progressive video at 50 fps as per BT.1120.</entry> | ||
206 | </row> | ||
207 | <row> | ||
208 | <entry>V4L2_DV_1080P60</entry> | ||
209 | <entry>18</entry> | ||
210 | <entry>1920x1080 progressive video at 60 fps as per BT.1120.</entry> | ||
211 | </row> | ||
212 | </tbody> | ||
213 | </tgroup> | ||
214 | </table> | ||
215 | </refsect1> | ||
216 | |||
217 | <refsect1> | ||
218 | &return-value; | ||
219 | |||
220 | <variablelist> | ||
221 | <varlistentry> | ||
222 | <term><errorcode>EINVAL</errorcode></term> | ||
223 | <listitem> | ||
224 | <para>The &v4l2-dv-enum-preset; <structfield>index</structfield> | ||
225 | is out of bounds.</para> | ||
226 | </listitem> | ||
227 | </varlistentry> | ||
228 | </variablelist> | ||
229 | </refsect1> | ||
230 | </refentry> | ||
231 | |||
232 | <!-- | ||
233 | Local Variables: | ||
234 | mode: sgml | ||
235 | sgml-parent-document: "v4l2.sgml" | ||
236 | indent-tabs-mode: nil | ||
237 | End: | ||
238 | --> | ||
diff --git a/Documentation/DocBook/v4l/vidioc-enuminput.xml b/Documentation/DocBook/v4l/vidioc-enuminput.xml index 414856b8247..71b868e2fb8 100644 --- a/Documentation/DocBook/v4l/vidioc-enuminput.xml +++ b/Documentation/DocBook/v4l/vidioc-enuminput.xml | |||
@@ -124,7 +124,13 @@ current input.</entry> | |||
124 | </row> | 124 | </row> |
125 | <row> | 125 | <row> |
126 | <entry>__u32</entry> | 126 | <entry>__u32</entry> |
127 | <entry><structfield>reserved</structfield>[4]</entry> | 127 | <entry><structfield>capabilities</structfield></entry> |
128 | <entry>This field provides capabilities for the | ||
129 | input. See <xref linkend="input-capabilities" /> for flags.</entry> | ||
130 | </row> | ||
131 | <row> | ||
132 | <entry>__u32</entry> | ||
133 | <entry><structfield>reserved</structfield>[3]</entry> | ||
128 | <entry>Reserved for future extensions. Drivers must set | 134 | <entry>Reserved for future extensions. Drivers must set |
129 | the array to zero.</entry> | 135 | the array to zero.</entry> |
130 | </row> | 136 | </row> |
@@ -261,6 +267,34 @@ flag is set Macrovision has been detected.</entry> | |||
261 | </tbody> | 267 | </tbody> |
262 | </tgroup> | 268 | </tgroup> |
263 | </table> | 269 | </table> |
270 | |||
271 | <!-- Capability flags based on video timings RFC by Muralidharan | ||
272 | Karicheri, titled RFC (v1.2): V4L - Support for video timings at the | ||
273 | input/output interface to linux-media@vger.kernel.org on 19 Oct 2009. | ||
274 | --> | ||
275 | <table frame="none" pgwide="1" id="input-capabilities"> | ||
276 | <title>Input capabilities</title> | ||
277 | <tgroup cols="3"> | ||
278 | &cs-def; | ||
279 | <tbody valign="top"> | ||
280 | <row> | ||
281 | <entry><constant>V4L2_IN_CAP_PRESETS</constant></entry> | ||
282 | <entry>0x00000001</entry> | ||
283 | <entry>This input supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry> | ||
284 | </row> | ||
285 | <row> | ||
286 | <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry> | ||
287 | <entry>0x00000002</entry> | ||
288 | <entry>This input supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry> | ||
289 | </row> | ||
290 | <row> | ||
291 | <entry><constant>V4L2_IN_CAP_STD</constant></entry> | ||
292 | <entry>0x00000004</entry> | ||
293 | <entry>This input supports setting the TV standard by using VIDIOC_S_STD.</entry> | ||
294 | </row> | ||
295 | </tbody> | ||
296 | </tgroup> | ||
297 | </table> | ||
264 | </refsect1> | 298 | </refsect1> |
265 | 299 | ||
266 | <refsect1> | 300 | <refsect1> |
diff --git a/Documentation/DocBook/v4l/vidioc-enumoutput.xml b/Documentation/DocBook/v4l/vidioc-enumoutput.xml index e8d16dcd50c..a281d26a195 100644 --- a/Documentation/DocBook/v4l/vidioc-enumoutput.xml +++ b/Documentation/DocBook/v4l/vidioc-enumoutput.xml | |||
@@ -114,7 +114,13 @@ details on video standards and how to switch see <xref | |||
114 | </row> | 114 | </row> |
115 | <row> | 115 | <row> |
116 | <entry>__u32</entry> | 116 | <entry>__u32</entry> |
117 | <entry><structfield>reserved</structfield>[4]</entry> | 117 | <entry><structfield>capabilities</structfield></entry> |
118 | <entry>This field provides capabilities for the | ||
119 | output. See <xref linkend="output-capabilities" /> for flags.</entry> | ||
120 | </row> | ||
121 | <row> | ||
122 | <entry>__u32</entry> | ||
123 | <entry><structfield>reserved</structfield>[3]</entry> | ||
118 | <entry>Reserved for future extensions. Drivers must set | 124 | <entry>Reserved for future extensions. Drivers must set |
119 | the array to zero.</entry> | 125 | the array to zero.</entry> |
120 | </row> | 126 | </row> |
@@ -147,6 +153,34 @@ CVBS, S-Video, RGB.</entry> | |||
147 | </tgroup> | 153 | </tgroup> |
148 | </table> | 154 | </table> |
149 | 155 | ||
156 | <!-- Capabilities flags based on video timings RFC by Muralidharan | ||
157 | Karicheri, titled RFC (v1.2): V4L - Support for video timings at the | ||
158 | input/output interface to linux-media@vger.kernel.org on 19 Oct 2009. | ||
159 | --> | ||
160 | <table frame="none" pgwide="1" id="output-capabilities"> | ||
161 | <title>Output capabilities</title> | ||
162 | <tgroup cols="3"> | ||
163 | &cs-def; | ||
164 | <tbody valign="top"> | ||
165 | <row> | ||
166 | <entry><constant>V4L2_OUT_CAP_PRESETS</constant></entry> | ||
167 | <entry>0x00000001</entry> | ||
168 | <entry>This output supports setting DV presets by using VIDIOC_S_DV_PRESET.</entry> | ||
169 | </row> | ||
170 | <row> | ||
171 | <entry><constant>V4L2_OUT_CAP_CUSTOM_TIMINGS</constant></entry> | ||
172 | <entry>0x00000002</entry> | ||
173 | <entry>This output supports setting custom video timings by using VIDIOC_S_DV_TIMINGS.</entry> | ||
174 | </row> | ||
175 | <row> | ||
176 | <entry><constant>V4L2_OUT_CAP_STD</constant></entry> | ||
177 | <entry>0x00000004</entry> | ||
178 | <entry>This output supports setting the TV standard by using VIDIOC_S_STD.</entry> | ||
179 | </row> | ||
180 | </tbody> | ||
181 | </tgroup> | ||
182 | </table> | ||
183 | |||
150 | </refsect1> | 184 | </refsect1> |
151 | <refsect1> | 185 | <refsect1> |
152 | &return-value; | 186 | &return-value; |
diff --git a/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml b/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml new file mode 100644 index 00000000000..3c6784e132f --- /dev/null +++ b/Documentation/DocBook/v4l/vidioc-g-dv-preset.xml | |||
@@ -0,0 +1,111 @@ | |||
1 | <refentry id="vidioc-g-dv-preset"> | ||
2 | <refmeta> | ||
3 | <refentrytitle>ioctl VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET</refentrytitle> | ||
4 | &manvol; | ||
5 | </refmeta> | ||
6 | |||
7 | <refnamediv> | ||
8 | <refname>VIDIOC_G_DV_PRESET</refname> | ||
9 | <refname>VIDIOC_S_DV_PRESET</refname> | ||
10 | <refpurpose>Query or select the DV preset of the current input or output</refpurpose> | ||
11 | </refnamediv> | ||
12 | |||
13 | <refsynopsisdiv> | ||
14 | <funcsynopsis> | ||
15 | <funcprototype> | ||
16 | <funcdef>int <function>ioctl</function></funcdef> | ||
17 | <paramdef>int <parameter>fd</parameter></paramdef> | ||
18 | <paramdef>int <parameter>request</parameter></paramdef> | ||
19 | <paramdef>&v4l2-dv-preset; | ||
20 | *<parameter>argp</parameter></paramdef> | ||
21 | </funcprototype> | ||
22 | </funcsynopsis> | ||
23 | </refsynopsisdiv> | ||
24 | |||
25 | <refsect1> | ||
26 | <title>Arguments</title> | ||
27 | |||
28 | <variablelist> | ||
29 | <varlistentry> | ||
30 | <term><parameter>fd</parameter></term> | ||
31 | <listitem> | ||
32 | <para>&fd;</para> | ||
33 | </listitem> | ||
34 | </varlistentry> | ||
35 | <varlistentry> | ||
36 | <term><parameter>request</parameter></term> | ||
37 | <listitem> | ||
38 | <para>VIDIOC_G_DV_PRESET, VIDIOC_S_DV_PRESET</para> | ||
39 | </listitem> | ||
40 | </varlistentry> | ||
41 | <varlistentry> | ||
42 | <term><parameter>argp</parameter></term> | ||
43 | <listitem> | ||
44 | <para></para> | ||
45 | </listitem> | ||
46 | </varlistentry> | ||
47 | </variablelist> | ||
48 | </refsect1> | ||
49 | |||
50 | <refsect1> | ||
51 | <title>Description</title> | ||
52 | <para>To query and select the current DV preset, applications | ||
53 | use the <constant>VIDIOC_G_DV_PRESET</constant> and <constant>VIDIOC_S_DV_PRESET</constant> | ||
54 | ioctls which take a pointer to a &v4l2-dv-preset; type as argument. | ||
55 | Applications must zero the reserved array in &v4l2-dv-preset;. | ||
56 | <constant>VIDIOC_G_DV_PRESET</constant> returns a dv preset in the field | ||
57 | <structfield>preset</structfield> of &v4l2-dv-preset;.</para> | ||
58 | |||
59 | <para><constant>VIDIOC_S_DV_PRESET</constant> accepts a pointer to a &v4l2-dv-preset; | ||
60 | that has the preset value to be set. Applications must zero the reserved array in &v4l2-dv-preset;. | ||
61 | If the preset is not supported, it returns an &EINVAL; </para> | ||
62 | </refsect1> | ||
63 | |||
64 | <refsect1> | ||
65 | &return-value; | ||
66 | |||
67 | <variablelist> | ||
68 | <varlistentry> | ||
69 | <term><errorcode>EINVAL</errorcode></term> | ||
70 | <listitem> | ||
71 | <para>This ioctl is not supported, or the | ||
72 | <constant>VIDIOC_S_DV_PRESET</constant>,<constant>VIDIOC_S_DV_PRESET</constant> parameter was unsuitable.</para> | ||
73 | </listitem> | ||
74 | </varlistentry> | ||
75 | <varlistentry> | ||
76 | <term><errorcode>EBUSY</errorcode></term> | ||
77 | <listitem> | ||
78 | <para>The device is busy and therefore can not change the preset.</para> | ||
79 | </listitem> | ||
80 | </varlistentry> | ||
81 | </variablelist> | ||
82 | |||
83 | <table pgwide="1" frame="none" id="v4l2-dv-preset"> | ||
84 | <title>struct <structname>v4l2_dv_preset</structname></title> | ||
85 | <tgroup cols="3"> | ||
86 | &cs-str; | ||
87 | <tbody valign="top"> | ||
88 | <row> | ||
89 | <entry>__u32</entry> | ||
90 | <entry><structfield>preset</structfield></entry> | ||
91 | <entry>Preset value to represent the digital video timings</entry> | ||
92 | </row> | ||
93 | <row> | ||
94 | <entry>__u32</entry> | ||
95 | <entry><structfield>reserved[4]</structfield></entry> | ||
96 | <entry>Reserved fields for future use</entry> | ||
97 | </row> | ||
98 | </tbody> | ||
99 | </tgroup> | ||
100 | </table> | ||
101 | |||
102 | </refsect1> | ||
103 | </refentry> | ||
104 | |||
105 | <!-- | ||
106 | Local Variables: | ||
107 | mode: sgml | ||
108 | sgml-parent-document: "v4l2.sgml" | ||
109 | indent-tabs-mode: nil | ||
110 | End: | ||
111 | --> | ||
diff --git a/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml b/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml new file mode 100644 index 00000000000..ecc19576bb8 --- /dev/null +++ b/Documentation/DocBook/v4l/vidioc-g-dv-timings.xml | |||
@@ -0,0 +1,224 @@ | |||
1 | <refentry id="vidioc-g-dv-timings"> | ||
2 | <refmeta> | ||
3 | <refentrytitle>ioctl VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS</refentrytitle> | ||
4 | &manvol; | ||
5 | </refmeta> | ||
6 | |||
7 | <refnamediv> | ||
8 | <refname>VIDIOC_G_DV_TIMINGS</refname> | ||
9 | <refname>VIDIOC_S_DV_TIMINGS</refname> | ||
10 | <refpurpose>Get or set custom DV timings for input or output</refpurpose> | ||
11 | </refnamediv> | ||
12 | |||
13 | <refsynopsisdiv> | ||
14 | <funcsynopsis> | ||
15 | <funcprototype> | ||
16 | <funcdef>int <function>ioctl</function></funcdef> | ||
17 | <paramdef>int <parameter>fd</parameter></paramdef> | ||
18 | <paramdef>int <parameter>request</parameter></paramdef> | ||
19 | <paramdef>&v4l2-dv-timings; | ||
20 | *<parameter>argp</parameter></paramdef> | ||
21 | </funcprototype> | ||
22 | </funcsynopsis> | ||
23 | </refsynopsisdiv> | ||
24 | |||
25 | <refsect1> | ||
26 | <title>Arguments</title> | ||
27 | |||
28 | <variablelist> | ||
29 | <varlistentry> | ||
30 | <term><parameter>fd</parameter></term> | ||
31 | <listitem> | ||
32 | <para>&fd;</para> | ||
33 | </listitem> | ||
34 | </varlistentry> | ||
35 | <varlistentry> | ||
36 | <term><parameter>request</parameter></term> | ||
37 | <listitem> | ||
38 | <para>VIDIOC_G_DV_TIMINGS, VIDIOC_S_DV_TIMINGS</para> | ||
39 | </listitem> | ||
40 | </varlistentry> | ||
41 | <varlistentry> | ||
42 | <term><parameter>argp</parameter></term> | ||
43 | <listitem> | ||
44 | <para></para> | ||
45 | </listitem> | ||
46 | </varlistentry> | ||
47 | </variablelist> | ||
48 | </refsect1> | ||
49 | |||
50 | <refsect1> | ||
51 | <title>Description</title> | ||
52 | <para>To set custom DV timings for the input or output, applications use the | ||
53 | <constant>VIDIOC_S_DV_TIMINGS</constant> ioctl and to get the current custom timings, | ||
54 | applications use the <constant>VIDIOC_G_DV_TIMINGS</constant> ioctl. The detailed timing | ||
55 | information is filled in using the structure &v4l2-dv-timings;. These ioctls take | ||
56 | a pointer to the &v4l2-dv-timings; structure as argument. If the ioctl is not supported | ||
57 | or the timing values are not correct, the driver returns &EINVAL;.</para> | ||
58 | </refsect1> | ||
59 | |||
60 | <refsect1> | ||
61 | &return-value; | ||
62 | |||
63 | <variablelist> | ||
64 | <varlistentry> | ||
65 | <term><errorcode>EINVAL</errorcode></term> | ||
66 | <listitem> | ||
67 | <para>This ioctl is not supported, or the | ||
68 | <constant>VIDIOC_S_DV_TIMINGS</constant> parameter was unsuitable.</para> | ||
69 | </listitem> | ||
70 | </varlistentry> | ||
71 | <varlistentry> | ||
72 | <term><errorcode>EBUSY</errorcode></term> | ||
73 | <listitem> | ||
74 | <para>The device is busy and therefore can not change the timings.</para> | ||
75 | </listitem> | ||
76 | </varlistentry> | ||
77 | </variablelist> | ||
78 | |||
79 | <table pgwide="1" frame="none" id="v4l2-bt-timings"> | ||
80 | <title>struct <structname>v4l2_bt_timings</structname></title> | ||
81 | <tgroup cols="3"> | ||
82 | &cs-str; | ||
83 | <tbody valign="top"> | ||
84 | <row> | ||
85 | <entry>__u32</entry> | ||
86 | <entry><structfield>width</structfield></entry> | ||
87 | <entry>Width of the active video in pixels</entry> | ||
88 | </row> | ||
89 | <row> | ||
90 | <entry>__u32</entry> | ||
91 | <entry><structfield>height</structfield></entry> | ||
92 | <entry>Height of the active video in lines</entry> | ||
93 | </row> | ||
94 | <row> | ||
95 | <entry>__u32</entry> | ||
96 | <entry><structfield>interlaced</structfield></entry> | ||
97 | <entry>Progressive (0) or interlaced (1)</entry> | ||
98 | </row> | ||
99 | <row> | ||
100 | <entry>__u32</entry> | ||
101 | <entry><structfield>polarities</structfield></entry> | ||
102 | <entry>This is a bit mask that defines polarities of sync signals. | ||
103 | 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 | ||
104 | (1) it is positive polarity and if is cleared (0), it is negative polarity.</entry> | ||
105 | </row> | ||
106 | <row> | ||
107 | <entry>__u64</entry> | ||
108 | <entry><structfield>pixelclock</structfield></entry> | ||
109 | <entry>Pixel clock in Hz. Ex. 74.25MHz->74250000</entry> | ||
110 | </row> | ||
111 | <row> | ||
112 | <entry>__u32</entry> | ||
113 | <entry><structfield>hfrontporch</structfield></entry> | ||
114 | <entry>Horizontal front porch in pixels</entry> | ||
115 | </row> | ||
116 | <row> | ||
117 | <entry>__u32</entry> | ||
118 | <entry><structfield>hsync</structfield></entry> | ||
119 | <entry>Horizontal sync length in pixels</entry> | ||
120 | </row> | ||
121 | <row> | ||
122 | <entry>__u32</entry> | ||
123 | <entry><structfield>hbackporch</structfield></entry> | ||
124 | <entry>Horizontal back porch in pixels</entry> | ||
125 | </row> | ||
126 | <row> | ||
127 | <entry>__u32</entry> | ||
128 | <entry><structfield>vfrontporch</structfield></entry> | ||
129 | <entry>Vertical front porch in lines</entry> | ||
130 | </row> | ||
131 | <row> | ||
132 | <entry>__u32</entry> | ||
133 | <entry><structfield>vsync</structfield></entry> | ||
134 | <entry>Vertical sync length in lines</entry> | ||
135 | </row> | ||
136 | <row> | ||
137 | <entry>__u32</entry> | ||
138 | <entry><structfield>vbackporch</structfield></entry> | ||
139 | <entry>Vertical back porch in lines</entry> | ||
140 | </row> | ||
141 | <row> | ||
142 | <entry>__u32</entry> | ||
143 | <entry><structfield>il_vfrontporch</structfield></entry> | ||
144 | <entry>Vertical front porch in lines for bottom field of interlaced field formats</entry> | ||
145 | </row> | ||
146 | <row> | ||
147 | <entry>__u32</entry> | ||
148 | <entry><structfield>il_vsync</structfield></entry> | ||
149 | <entry>Vertical sync length in lines for bottom field of interlaced field formats</entry> | ||
150 | </row> | ||
151 | <row> | ||
152 | <entry>__u32</entry> | ||
153 | <entry><structfield>il_vbackporch</structfield></entry> | ||
154 | <entry>Vertical back porch in lines for bottom field of interlaced field formats</entry> | ||
155 | </row> | ||
156 | </tbody> | ||
157 | </tgroup> | ||
158 | </table> | ||
159 | |||
160 | <table pgwide="1" frame="none" id="v4l2-dv-timings"> | ||
161 | <title>struct <structname>v4l2_dv_timings</structname></title> | ||
162 | <tgroup cols="4"> | ||
163 | &cs-str; | ||
164 | <tbody valign="top"> | ||
165 | <row> | ||
166 | <entry>__u32</entry> | ||
167 | <entry><structfield>type</structfield></entry> | ||
168 | <entry></entry> | ||
169 | <entry>Type of DV timings as listed in <xref linkend="dv-timing-types"/>.</entry> | ||
170 | </row> | ||
171 | <row> | ||
172 | <entry>union</entry> | ||
173 | <entry><structfield></structfield></entry> | ||
174 | <entry></entry> | ||
175 | </row> | ||
176 | <row> | ||
177 | <entry></entry> | ||
178 | <entry>&v4l2-bt-timings;</entry> | ||
179 | <entry><structfield>bt</structfield></entry> | ||
180 | <entry>Timings defined by BT.656/1120 specifications</entry> | ||
181 | </row> | ||
182 | <row> | ||
183 | <entry></entry> | ||
184 | <entry>__u32</entry> | ||
185 | <entry><structfield>reserved</structfield>[32]</entry> | ||
186 | <entry></entry> | ||
187 | </row> | ||
188 | </tbody> | ||
189 | </tgroup> | ||
190 | </table> | ||
191 | |||
192 | <table pgwide="1" frame="none" id="dv-timing-types"> | ||
193 | <title>DV Timing types</title> | ||
194 | <tgroup cols="3"> | ||
195 | &cs-str; | ||
196 | <tbody valign="top"> | ||
197 | <row> | ||
198 | <entry>Timing type</entry> | ||
199 | <entry>value</entry> | ||
200 | <entry>Description</entry> | ||
201 | </row> | ||
202 | <row> | ||
203 | <entry></entry> | ||
204 | <entry></entry> | ||
205 | <entry></entry> | ||
206 | </row> | ||
207 | <row> | ||
208 | <entry>V4L2_DV_BT_656_1120</entry> | ||
209 | <entry>0</entry> | ||
210 | <entry>BT.656/1120 timings</entry> | ||
211 | </row> | ||
212 | </tbody> | ||
213 | </tgroup> | ||
214 | </table> | ||
215 | </refsect1> | ||
216 | </refentry> | ||
217 | |||
218 | <!-- | ||
219 | Local Variables: | ||
220 | mode: sgml | ||
221 | sgml-parent-document: "v4l2.sgml" | ||
222 | indent-tabs-mode: nil | ||
223 | End: | ||
224 | --> | ||
diff --git a/Documentation/DocBook/v4l/vidioc-g-std.xml b/Documentation/DocBook/v4l/vidioc-g-std.xml index b6f5d267e85..912f8513e5d 100644 --- a/Documentation/DocBook/v4l/vidioc-g-std.xml +++ b/Documentation/DocBook/v4l/vidioc-g-std.xml | |||
@@ -86,6 +86,12 @@ standards.</para> | |||
86 | <constant>VIDIOC_S_STD</constant> parameter was unsuitable.</para> | 86 | <constant>VIDIOC_S_STD</constant> parameter was unsuitable.</para> |
87 | </listitem> | 87 | </listitem> |
88 | </varlistentry> | 88 | </varlistentry> |
89 | <varlistentry> | ||
90 | <term><errorcode>EBUSY</errorcode></term> | ||
91 | <listitem> | ||
92 | <para>The device is busy and therefore can not change the standard</para> | ||
93 | </listitem> | ||
94 | </varlistentry> | ||
89 | </variablelist> | 95 | </variablelist> |
90 | </refsect1> | 96 | </refsect1> |
91 | </refentry> | 97 | </refentry> |
diff --git a/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml b/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml new file mode 100644 index 00000000000..87e4f0f6151 --- /dev/null +++ b/Documentation/DocBook/v4l/vidioc-query-dv-preset.xml | |||
@@ -0,0 +1,85 @@ | |||
1 | <refentry id="vidioc-query-dv-preset"> | ||
2 | <refmeta> | ||
3 | <refentrytitle>ioctl VIDIOC_QUERY_DV_PRESET</refentrytitle> | ||
4 | &manvol; | ||
5 | </refmeta> | ||
6 | |||
7 | <refnamediv> | ||
8 | <refname>VIDIOC_QUERY_DV_PRESET</refname> | ||
9 | <refpurpose>Sense the DV preset received by the current | ||
10 | input</refpurpose> | ||
11 | </refnamediv> | ||
12 | |||
13 | <refsynopsisdiv> | ||
14 | <funcsynopsis> | ||
15 | <funcprototype> | ||
16 | <funcdef>int <function>ioctl</function></funcdef> | ||
17 | <paramdef>int <parameter>fd</parameter></paramdef> | ||
18 | <paramdef>int <parameter>request</parameter></paramdef> | ||
19 | <paramdef>&v4l2-dv-preset; *<parameter>argp</parameter></paramdef> | ||
20 | </funcprototype> | ||
21 | </funcsynopsis> | ||
22 | </refsynopsisdiv> | ||
23 | |||
24 | <refsect1> | ||
25 | <title>Arguments</title> | ||
26 | |||
27 | <variablelist> | ||
28 | <varlistentry> | ||
29 | <term><parameter>fd</parameter></term> | ||
30 | <listitem> | ||
31 | <para>&fd;</para> | ||
32 | </listitem> | ||
33 | </varlistentry> | ||
34 | <varlistentry> | ||
35 | <term><parameter>request</parameter></term> | ||
36 | <listitem> | ||
37 | <para>VIDIOC_QUERY_DV_PRESET</para> | ||
38 | </listitem> | ||
39 | </varlistentry> | ||
40 | <varlistentry> | ||
41 | <term><parameter>argp</parameter></term> | ||
42 | <listitem> | ||
43 | <para></para> | ||
44 | </listitem> | ||
45 | </varlistentry> | ||
46 | </variablelist> | ||
47 | </refsect1> | ||
48 | |||
49 | <refsect1> | ||
50 | <title>Description</title> | ||
51 | |||
52 | <para>The hardware may be able to detect the current DV preset | ||
53 | automatically, similar to sensing the video standard. To do so, applications | ||
54 | call <constant> VIDIOC_QUERY_DV_PRESET</constant> with a pointer to a | ||
55 | &v4l2-dv-preset; type. Once the hardware detects a preset, that preset is | ||
56 | returned in the preset field of &v4l2-dv-preset;. When detection is not | ||
57 | possible or fails, the value V4L2_DV_INVALID is returned.</para> | ||
58 | </refsect1> | ||
59 | |||
60 | <refsect1> | ||
61 | &return-value; | ||
62 | <variablelist> | ||
63 | <varlistentry> | ||
64 | <term><errorcode>EINVAL</errorcode></term> | ||
65 | <listitem> | ||
66 | <para>This ioctl is not supported.</para> | ||
67 | </listitem> | ||
68 | </varlistentry> | ||
69 | <varlistentry> | ||
70 | <term><errorcode>EBUSY</errorcode></term> | ||
71 | <listitem> | ||
72 | <para>The device is busy and therefore can not sense the preset</para> | ||
73 | </listitem> | ||
74 | </varlistentry> | ||
75 | </variablelist> | ||
76 | </refsect1> | ||
77 | </refentry> | ||
78 | |||
79 | <!-- | ||
80 | Local Variables: | ||
81 | mode: sgml | ||
82 | sgml-parent-document: "v4l2.sgml" | ||
83 | indent-tabs-mode: nil | ||
84 | End: | ||
85 | --> | ||
diff --git a/Documentation/DocBook/v4l/vidioc-querystd.xml b/Documentation/DocBook/v4l/vidioc-querystd.xml index b5a7ff93448..1a9e6039309 100644 --- a/Documentation/DocBook/v4l/vidioc-querystd.xml +++ b/Documentation/DocBook/v4l/vidioc-querystd.xml | |||
@@ -70,6 +70,12 @@ current video input or output.</para> | |||
70 | <para>This ioctl is not supported.</para> | 70 | <para>This ioctl is not supported.</para> |
71 | </listitem> | 71 | </listitem> |
72 | </varlistentry> | 72 | </varlistentry> |
73 | <varlistentry> | ||
74 | <term><errorcode>EBUSY</errorcode></term> | ||
75 | <listitem> | ||
76 | <para>The device is busy and therefore can not detect the standard</para> | ||
77 | </listitem> | ||
78 | </varlistentry> | ||
73 | </variablelist> | 79 | </variablelist> |
74 | </refsect1> | 80 | </refsect1> |
75 | </refentry> | 81 | </refentry> |
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 319d9838e87..1800a62cf13 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt | |||
@@ -12,6 +12,7 @@ m5602 0402:5602 ALi Video Camera Controller | |||
12 | spca501 040a:0002 Kodak DVC-325 | 12 | spca501 040a:0002 Kodak DVC-325 |
13 | spca500 040a:0300 Kodak EZ200 | 13 | spca500 040a:0300 Kodak EZ200 |
14 | zc3xx 041e:041e Creative WebCam Live! | 14 | zc3xx 041e:041e Creative WebCam Live! |
15 | ov519 041e:4003 Video Blaster WebCam Go Plus | ||
15 | spca500 041e:400a Creative PC-CAM 300 | 16 | spca500 041e:400a Creative PC-CAM 300 |
16 | sunplus 041e:400b Creative PC-CAM 600 | 17 | sunplus 041e:400b Creative PC-CAM 600 |
17 | sunplus 041e:4012 PC-Cam350 | 18 | sunplus 041e:4012 PC-Cam350 |
@@ -168,10 +169,14 @@ sunplus 055f:c650 Mustek MDC5500Z | |||
168 | zc3xx 055f:d003 Mustek WCam300A | 169 | zc3xx 055f:d003 Mustek WCam300A |
169 | zc3xx 055f:d004 Mustek WCam300 AN | 170 | zc3xx 055f:d004 Mustek WCam300 AN |
170 | conex 0572:0041 Creative Notebook cx11646 | 171 | conex 0572:0041 Creative Notebook cx11646 |
172 | ov519 05a9:0511 Video Blaster WebCam 3/WebCam Plus, D-Link USB Digital Video Camera | ||
173 | ov519 05a9:0518 Creative WebCam | ||
171 | ov519 05a9:0519 OV519 Microphone | 174 | ov519 05a9:0519 OV519 Microphone |
172 | ov519 05a9:0530 OmniVision | 175 | ov519 05a9:0530 OmniVision |
176 | ov519 05a9:2800 OmniVision SuperCAM | ||
173 | ov519 05a9:4519 Webcam Classic | 177 | ov519 05a9:4519 Webcam Classic |
174 | ov519 05a9:8519 OmniVision | 178 | ov519 05a9:8519 OmniVision |
179 | ov519 05a9:a511 D-Link USB Digital Video Camera | ||
175 | ov519 05a9:a518 D-Link DSB-C310 Webcam | 180 | ov519 05a9:a518 D-Link DSB-C310 Webcam |
176 | sunplus 05da:1018 Digital Dream Enigma 1.3 | 181 | sunplus 05da:1018 Digital Dream Enigma 1.3 |
177 | stk014 05e1:0893 Syntek DV4000 | 182 | stk014 05e1:0893 Syntek DV4000 |
@@ -187,7 +192,7 @@ ov534 06f8:3002 Hercules Blog Webcam | |||
187 | ov534 06f8:3003 Hercules Dualpix HD Weblog | 192 | ov534 06f8:3003 Hercules Dualpix HD Weblog |
188 | sonixj 06f8:3004 Hercules Classic Silver | 193 | sonixj 06f8:3004 Hercules Classic Silver |
189 | sonixj 06f8:3008 Hercules Deluxe Optical Glass | 194 | sonixj 06f8:3008 Hercules Deluxe Optical Glass |
190 | pac7311 06f8:3009 Hercules Classic Link | 195 | pac7302 06f8:3009 Hercules Classic Link |
191 | spca508 0733:0110 ViewQuest VQ110 | 196 | spca508 0733:0110 ViewQuest VQ110 |
192 | spca501 0733:0401 Intel Create and Share | 197 | spca501 0733:0401 Intel Create and Share |
193 | spca501 0733:0402 ViewQuest M318B | 198 | spca501 0733:0402 ViewQuest M318B |
@@ -199,6 +204,7 @@ sunplus 0733:2221 Mercury Digital Pro 3.1p | |||
199 | sunplus 0733:3261 Concord 3045 spca536a | 204 | sunplus 0733:3261 Concord 3045 spca536a |
200 | sunplus 0733:3281 Cyberpix S550V | 205 | sunplus 0733:3281 Cyberpix S550V |
201 | spca506 0734:043b 3DeMon USB Capture aka | 206 | spca506 0734:043b 3DeMon USB Capture aka |
207 | ov519 0813:0002 Dual Mode USB Camera Plus | ||
202 | spca500 084d:0003 D-Link DSC-350 | 208 | spca500 084d:0003 D-Link DSC-350 |
203 | spca500 08ca:0103 Aiptek PocketDV | 209 | spca500 08ca:0103 Aiptek PocketDV |
204 | sunplus 08ca:0104 Aiptek PocketDVII 1.3 | 210 | sunplus 08ca:0104 Aiptek PocketDVII 1.3 |
@@ -236,15 +242,15 @@ pac7311 093a:2603 Philips SPC 500 NC | |||
236 | pac7311 093a:2608 Trust WB-3300p | 242 | pac7311 093a:2608 Trust WB-3300p |
237 | pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 | 243 | pac7311 093a:260e Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 |
238 | pac7311 093a:260f SnakeCam | 244 | pac7311 093a:260f SnakeCam |
239 | pac7311 093a:2620 Apollo AC-905 | 245 | pac7302 093a:2620 Apollo AC-905 |
240 | pac7311 093a:2621 PAC731x | 246 | pac7302 093a:2621 PAC731x |
241 | pac7311 093a:2622 Genius Eye 312 | 247 | pac7302 093a:2622 Genius Eye 312 |
242 | pac7311 093a:2624 PAC7302 | 248 | pac7302 093a:2624 PAC7302 |
243 | pac7311 093a:2626 Labtec 2200 | 249 | pac7302 093a:2626 Labtec 2200 |
244 | pac7311 093a:2628 Genius iLook 300 | 250 | pac7302 093a:2628 Genius iLook 300 |
245 | pac7311 093a:2629 Genious iSlim 300 | 251 | pac7302 093a:2629 Genious iSlim 300 |
246 | pac7311 093a:262a Webcam 300k | 252 | pac7302 093a:262a Webcam 300k |
247 | pac7311 093a:262c Philips SPC 230 NC | 253 | pac7302 093a:262c Philips SPC 230 NC |
248 | jeilinj 0979:0280 Sakar 57379 | 254 | jeilinj 0979:0280 Sakar 57379 |
249 | zc3xx 0ac8:0302 Z-star Vimicro zc0302 | 255 | zc3xx 0ac8:0302 Z-star Vimicro zc0302 |
250 | vc032x 0ac8:0321 Vimicro generic vc0321 | 256 | vc032x 0ac8:0321 Vimicro generic vc0321 |
@@ -259,6 +265,7 @@ vc032x 0ac8:c002 Sony embedded vimicro | |||
259 | vc032x 0ac8:c301 Samsung Q1 Ultra Premium | 265 | vc032x 0ac8:c301 Samsung Q1 Ultra Premium |
260 | spca508 0af9:0010 Hama USB Sightcam 100 | 266 | spca508 0af9:0010 Hama USB Sightcam 100 |
261 | spca508 0af9:0011 Hama USB Sightcam 100 | 267 | spca508 0af9:0011 Hama USB Sightcam 100 |
268 | ov519 0b62:0059 iBOT2 Webcam | ||
262 | sonixb 0c45:6001 Genius VideoCAM NB | 269 | sonixb 0c45:6001 Genius VideoCAM NB |
263 | sonixb 0c45:6005 Microdia Sweex Mini Webcam | 270 | sonixb 0c45:6005 Microdia Sweex Mini Webcam |
264 | sonixb 0c45:6007 Sonix sn9c101 + Tas5110D | 271 | sonixb 0c45:6007 Sonix sn9c101 + Tas5110D |
@@ -318,8 +325,10 @@ sn9c20x 0c45:62b3 PC Camera (SN9C202 + OV9655) | |||
318 | sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660) | 325 | sn9c20x 0c45:62bb PC Camera (SN9C202 + OV7660) |
319 | sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R) | 326 | sn9c20x 0c45:62bc PC Camera (SN9C202 + HV7131R) |
320 | sunplus 0d64:0303 Sunplus FashionCam DXG | 327 | sunplus 0d64:0303 Sunplus FashionCam DXG |
328 | ov519 0e96:c001 TRUST 380 USB2 SPACEC@M | ||
321 | etoms 102c:6151 Qcam Sangha CIF | 329 | etoms 102c:6151 Qcam Sangha CIF |
322 | etoms 102c:6251 Qcam xxxxxx VGA | 330 | etoms 102c:6251 Qcam xxxxxx VGA |
331 | ov519 1046:9967 W9967CF/W9968CF WebCam IC, Video Blaster WebCam Go | ||
323 | zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 | 332 | zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 |
324 | spca561 10fd:7e50 FlyCam Usb 100 | 333 | spca561 10fd:7e50 FlyCam Usb 100 |
325 | zc3xx 10fd:8050 Typhoon Webshot II USB 300k | 334 | zc3xx 10fd:8050 Typhoon Webshot II USB 300k |
@@ -332,7 +341,12 @@ spca501 1776:501c Arowana 300K CMOS Camera | |||
332 | t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops | 341 | t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops |
333 | vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC | 342 | vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC |
334 | pac207 2001:f115 D-Link DSB-C120 | 343 | pac207 2001:f115 D-Link DSB-C120 |
344 | sq905c 2770:9050 sq905c | ||
345 | sq905c 2770:905c DualCamera | ||
346 | sq905 2770:9120 Argus Digital Camera DC1512 | ||
347 | sq905c 2770:913d sq905c | ||
335 | spca500 2899:012c Toptro Industrial | 348 | spca500 2899:012c Toptro Industrial |
349 | ov519 8020:ef04 ov519 | ||
336 | spca508 8086:0110 Intel Easy PC Camera | 350 | spca508 8086:0110 Intel Easy PC Camera |
337 | spca500 8086:0630 Intel Pocket PC Camera | 351 | spca500 8086:0630 Intel Pocket PC Camera |
338 | spca506 99fa:8988 Grandtec V.cap | 352 | spca506 99fa:8988 Grandtec V.cap |
diff --git a/Documentation/video4linux/sh_mobile_ceu_camera.txt b/Documentation/video4linux/sh_mobile_ceu_camera.txt new file mode 100644 index 00000000000..2ae16349a78 --- /dev/null +++ b/Documentation/video4linux/sh_mobile_ceu_camera.txt | |||
@@ -0,0 +1,157 @@ | |||
1 | Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver | ||
2 | ======================================================================= | ||
3 | |||
4 | Terminology | ||
5 | ----------- | ||
6 | |||
7 | sensor scales: horizontal and vertical scales, configured by the sensor driver | ||
8 | host scales: -"- host driver | ||
9 | combined scales: sensor_scale * host_scale | ||
10 | |||
11 | |||
12 | Generic scaling / cropping scheme | ||
13 | --------------------------------- | ||
14 | |||
15 | -1-- | ||
16 | | | ||
17 | -2-- -\ | ||
18 | | --\ | ||
19 | | --\ | ||
20 | +-5-- -\ -- -3-- | ||
21 | | ---\ | ||
22 | | --- -4-- -\ | ||
23 | | -\ | ||
24 | | - -6-- | ||
25 | | | ||
26 | | - -6'- | ||
27 | | -/ | ||
28 | | --- -4'- -/ | ||
29 | | ---/ | ||
30 | +-5'- -/ | ||
31 | | -- -3'- | ||
32 | | --/ | ||
33 | | --/ | ||
34 | -2'- -/ | ||
35 | | | ||
36 | | | ||
37 | -1'- | ||
38 | |||
39 | Produced by user requests: | ||
40 | |||
41 | S_CROP(left / top = (5) - (1), width / height = (5') - (5)) | ||
42 | S_FMT(width / height = (6') - (6)) | ||
43 | |||
44 | Here: | ||
45 | |||
46 | (1) to (1') - whole max width or height | ||
47 | (1) to (2) - sensor cropped left or top | ||
48 | (2) to (2') - sensor cropped width or height | ||
49 | (3) to (3') - sensor scale | ||
50 | (3) to (4) - CEU cropped left or top | ||
51 | (4) to (4') - CEU cropped width or height | ||
52 | (5) to (5') - reverse sensor scale applied to CEU cropped width or height | ||
53 | (2) to (5) - reverse sensor scale applied to CEU cropped left or top | ||
54 | (6) to (6') - CEU scale - user window | ||
55 | |||
56 | |||
57 | S_FMT | ||
58 | ----- | ||
59 | |||
60 | Do not touch input rectangle - it is already optimal. | ||
61 | |||
62 | 1. Calculate current sensor scales: | ||
63 | |||
64 | scale_s = ((3') - (3)) / ((2') - (2)) | ||
65 | |||
66 | 2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at | ||
67 | current sensor scales onto input window - this is user S_CROP: | ||
68 | |||
69 | width_u = (5') - (5) = ((4') - (4)) * scale_s | ||
70 | |||
71 | 3. Calculate new combined scales from "effective" input window to requested user | ||
72 | window: | ||
73 | |||
74 | scale_comb = width_u / ((6') - (6)) | ||
75 | |||
76 | 4. Calculate sensor output window by applying combined scales to real input | ||
77 | window: | ||
78 | |||
79 | width_s_out = ((2') - (2)) / scale_comb | ||
80 | |||
81 | 5. Apply iterative sensor S_FMT for sensor output window. | ||
82 | |||
83 | subdev->video_ops->s_fmt(.width = width_s_out) | ||
84 | |||
85 | 6. Retrieve sensor output window (g_fmt) | ||
86 | |||
87 | 7. Calculate new sensor scales: | ||
88 | |||
89 | scale_s_new = ((3')_new - (3)_new) / ((2') - (2)) | ||
90 | |||
91 | 8. Calculate new CEU crop - apply sensor scales to previously calculated | ||
92 | "effective" crop: | ||
93 | |||
94 | width_ceu = (4')_new - (4)_new = width_u / scale_s_new | ||
95 | left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new | ||
96 | |||
97 | 9. Use CEU cropping to crop to the new window: | ||
98 | |||
99 | ceu_crop(.width = width_ceu, .left = left_ceu) | ||
100 | |||
101 | 10. Use CEU scaling to scale to the requested user window: | ||
102 | |||
103 | scale_ceu = width_ceu / width | ||
104 | |||
105 | |||
106 | S_CROP | ||
107 | ------ | ||
108 | |||
109 | If old scale applied to new crop is invalid produce nearest new scale possible | ||
110 | |||
111 | 1. Calculate current combined scales. | ||
112 | |||
113 | scale_comb = (((4') - (4)) / ((6') - (6))) * (((2') - (2)) / ((3') - (3))) | ||
114 | |||
115 | 2. Apply iterative sensor S_CROP for new input window. | ||
116 | |||
117 | 3. If old combined scales applied to new crop produce an impossible user window, | ||
118 | adjust scales to produce nearest possible window. | ||
119 | |||
120 | width_u_out = ((5') - (5)) / scale_comb | ||
121 | |||
122 | if (width_u_out > max) | ||
123 | scale_comb = ((5') - (5)) / max; | ||
124 | else if (width_u_out < min) | ||
125 | scale_comb = ((5') - (5)) / min; | ||
126 | |||
127 | 4. Issue G_CROP to retrieve actual input window. | ||
128 | |||
129 | 5. Using actual input window and calculated combined scales calculate sensor | ||
130 | target output window. | ||
131 | |||
132 | width_s_out = ((3') - (3)) = ((2') - (2)) / scale_comb | ||
133 | |||
134 | 6. Apply iterative S_FMT for new sensor target output window. | ||
135 | |||
136 | 7. Issue G_FMT to retrieve the actual sensor output window. | ||
137 | |||
138 | 8. Calculate sensor scales. | ||
139 | |||
140 | scale_s = ((3') - (3)) / ((2') - (2)) | ||
141 | |||
142 | 9. Calculate sensor output subwindow to be cropped on CEU by applying sensor | ||
143 | scales to the requested window. | ||
144 | |||
145 | width_ceu = ((5') - (5)) / scale_s | ||
146 | |||
147 | 10. Use CEU cropping for above calculated window. | ||
148 | |||
149 | 11. Calculate CEU scales from sensor scales from results of (10) and user window | ||
150 | from (3) | ||
151 | |||
152 | scale_ceu = calc_scale(((5') - (5)), &width_u_out) | ||
153 | |||
154 | 12. Apply CEU scales. | ||
155 | |||
156 | -- | ||
157 | Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index b806edaf3e7..74d677c8b03 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt | |||
@@ -561,6 +561,8 @@ video_device helper functions | |||
561 | 561 | ||
562 | There are a few useful helper functions: | 562 | There are a few useful helper functions: |
563 | 563 | ||
564 | - file/video_device private data | ||
565 | |||
564 | You can set/get driver private data in the video_device struct using: | 566 | You can set/get driver private data in the video_device struct using: |
565 | 567 | ||
566 | void *video_get_drvdata(struct video_device *vdev); | 568 | void *video_get_drvdata(struct video_device *vdev); |
@@ -575,8 +577,7 @@ struct video_device *video_devdata(struct file *file); | |||
575 | 577 | ||
576 | returns the video_device belonging to the file struct. | 578 | returns the video_device belonging to the file struct. |
577 | 579 | ||
578 | The final helper function combines video_get_drvdata with | 580 | The video_drvdata function combines video_get_drvdata with video_devdata: |
579 | video_devdata: | ||
580 | 581 | ||
581 | void *video_drvdata(struct file *file); | 582 | void *video_drvdata(struct file *file); |
582 | 583 | ||
@@ -584,6 +585,17 @@ You can go from a video_device struct to the v4l2_device struct using: | |||
584 | 585 | ||
585 | struct v4l2_device *v4l2_dev = vdev->v4l2_dev; | 586 | struct v4l2_device *v4l2_dev = vdev->v4l2_dev; |
586 | 587 | ||
588 | - Device node name | ||
589 | |||
590 | The video_device node kernel name can be retrieved using | ||
591 | |||
592 | const char *video_device_node_name(struct video_device *vdev); | ||
593 | |||
594 | The name is used as a hint by userspace tools such as udev. The function | ||
595 | should be used where possible instead of accessing the video_device::num and | ||
596 | video_device::minor fields. | ||
597 | |||
598 | |||
587 | video buffer helper functions | 599 | video buffer helper functions |
588 | ----------------------------- | 600 | ----------------------------- |
589 | 601 | ||
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index cf9dc12dfeb..7a9f69663f1 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c | |||
@@ -316,20 +316,23 @@ static struct soc_camera_platform_info camera_info = { | |||
316 | .format_name = "UYVY", | 316 | .format_name = "UYVY", |
317 | .format_depth = 16, | 317 | .format_depth = 16, |
318 | .format = { | 318 | .format = { |
319 | .pixelformat = V4L2_PIX_FMT_UYVY, | 319 | .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, |
320 | .colorspace = V4L2_COLORSPACE_SMPTE170M, | 320 | .colorspace = V4L2_COLORSPACE_SMPTE170M, |
321 | .field = V4L2_FIELD_NONE, | ||
321 | .width = 640, | 322 | .width = 640, |
322 | .height = 480, | 323 | .height = 480, |
323 | }, | 324 | }, |
324 | .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | | 325 | .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | |
325 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, | 326 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, |
326 | .set_capture = camera_set_capture, | 327 | .set_capture = camera_set_capture, |
327 | .link = { | 328 | }; |
328 | .bus_id = 0, | 329 | |
329 | .add_device = ap325rxa_camera_add, | 330 | struct soc_camera_link camera_link = { |
330 | .del_device = ap325rxa_camera_del, | 331 | .bus_id = 0, |
331 | .module_name = "soc_camera_platform", | 332 | .add_device = ap325rxa_camera_add, |
332 | }, | 333 | .del_device = ap325rxa_camera_del, |
334 | .module_name = "soc_camera_platform", | ||
335 | .priv = &camera_info, | ||
333 | }; | 336 | }; |
334 | 337 | ||
335 | static void dummy_release(struct device *dev) | 338 | static void dummy_release(struct device *dev) |
@@ -347,7 +350,7 @@ static struct platform_device camera_device = { | |||
347 | static int ap325rxa_camera_add(struct soc_camera_link *icl, | 350 | static int ap325rxa_camera_add(struct soc_camera_link *icl, |
348 | struct device *dev) | 351 | struct device *dev) |
349 | { | 352 | { |
350 | if (icl != &camera_info.link || camera_probe() <= 0) | 353 | if (icl != &camera_link || camera_probe() <= 0) |
351 | return -ENODEV; | 354 | return -ENODEV; |
352 | 355 | ||
353 | camera_info.dev = dev; | 356 | camera_info.dev = dev; |
@@ -357,7 +360,7 @@ static int ap325rxa_camera_add(struct soc_camera_link *icl, | |||
357 | 360 | ||
358 | static void ap325rxa_camera_del(struct soc_camera_link *icl) | 361 | static void ap325rxa_camera_del(struct soc_camera_link *icl) |
359 | { | 362 | { |
360 | if (icl != &camera_info.link) | 363 | if (icl != &camera_link) |
361 | return; | 364 | return; |
362 | 365 | ||
363 | platform_device_unregister(&camera_device); | 366 | platform_device_unregister(&camera_device); |
@@ -470,13 +473,15 @@ static struct ov772x_camera_info ov7725_info = { | |||
470 | .buswidth = SOCAM_DATAWIDTH_8, | 473 | .buswidth = SOCAM_DATAWIDTH_8, |
471 | .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, | 474 | .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, |
472 | .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), | 475 | .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), |
473 | .link = { | 476 | }; |
474 | .bus_id = 0, | 477 | |
475 | .power = ov7725_power, | 478 | static struct soc_camera_link ov7725_link = { |
476 | .board_info = &ap325rxa_i2c_camera[0], | 479 | .bus_id = 0, |
477 | .i2c_adapter_id = 0, | 480 | .power = ov7725_power, |
478 | .module_name = "ov772x", | 481 | .board_info = &ap325rxa_i2c_camera[0], |
479 | }, | 482 | .i2c_adapter_id = 0, |
483 | .module_name = "ov772x", | ||
484 | .priv = &ov7725_info, | ||
480 | }; | 485 | }; |
481 | 486 | ||
482 | static struct platform_device ap325rxa_camera[] = { | 487 | static struct platform_device ap325rxa_camera[] = { |
@@ -484,13 +489,13 @@ static struct platform_device ap325rxa_camera[] = { | |||
484 | .name = "soc-camera-pdrv", | 489 | .name = "soc-camera-pdrv", |
485 | .id = 0, | 490 | .id = 0, |
486 | .dev = { | 491 | .dev = { |
487 | .platform_data = &ov7725_info.link, | 492 | .platform_data = &ov7725_link, |
488 | }, | 493 | }, |
489 | }, { | 494 | }, { |
490 | .name = "soc-camera-pdrv", | 495 | .name = "soc-camera-pdrv", |
491 | .id = 1, | 496 | .id = 1, |
492 | .dev = { | 497 | .dev = { |
493 | .platform_data = &camera_info.link, | 498 | .platform_data = &camera_link, |
494 | }, | 499 | }, |
495 | }, | 500 | }, |
496 | }; | 501 | }; |
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 87438d6603d..9038d768a52 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/input/sh_keysc.h> | 19 | #include <linux/input/sh_keysc.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/usb/r8a66597.h> | 21 | #include <linux/usb/r8a66597.h> |
22 | #include <media/rj54n1cb0c.h> | ||
22 | #include <media/soc_camera.h> | 23 | #include <media/soc_camera.h> |
23 | #include <media/sh_mobile_ceu.h> | 24 | #include <media/sh_mobile_ceu.h> |
24 | #include <video/sh_mobile_lcdc.h> | 25 | #include <video/sh_mobile_lcdc.h> |
@@ -255,6 +256,9 @@ static struct i2c_board_info kfr2r09_i2c_camera = { | |||
255 | 256 | ||
256 | static struct clk *camera_clk; | 257 | static struct clk *camera_clk; |
257 | 258 | ||
259 | /* set VIO_CKO clock to 25MHz */ | ||
260 | #define CEU_MCLK_FREQ 25000000 | ||
261 | |||
258 | #define DRVCRB 0xA405018C | 262 | #define DRVCRB 0xA405018C |
259 | static int camera_power(struct device *dev, int mode) | 263 | static int camera_power(struct device *dev, int mode) |
260 | { | 264 | { |
@@ -267,8 +271,7 @@ static int camera_power(struct device *dev, int mode) | |||
267 | if (IS_ERR(camera_clk)) | 271 | if (IS_ERR(camera_clk)) |
268 | return PTR_ERR(camera_clk); | 272 | return PTR_ERR(camera_clk); |
269 | 273 | ||
270 | /* set VIO_CKO clock to 25MHz */ | 274 | rate = clk_round_rate(camera_clk, CEU_MCLK_FREQ); |
271 | rate = clk_round_rate(camera_clk, 25000000); | ||
272 | ret = clk_set_rate(camera_clk, rate); | 275 | ret = clk_set_rate(camera_clk, rate); |
273 | if (ret < 0) | 276 | if (ret < 0) |
274 | goto eclkrate; | 277 | goto eclkrate; |
@@ -318,11 +321,17 @@ eclkrate: | |||
318 | return ret; | 321 | return ret; |
319 | } | 322 | } |
320 | 323 | ||
324 | static struct rj54n1_pdata rj54n1_priv = { | ||
325 | .mclk_freq = CEU_MCLK_FREQ, | ||
326 | .ioctl_high = false, | ||
327 | }; | ||
328 | |||
321 | static struct soc_camera_link rj54n1_link = { | 329 | static struct soc_camera_link rj54n1_link = { |
322 | .power = camera_power, | 330 | .power = camera_power, |
323 | .board_info = &kfr2r09_i2c_camera, | 331 | .board_info = &kfr2r09_i2c_camera, |
324 | .i2c_adapter_id = 1, | 332 | .i2c_adapter_id = 1, |
325 | .module_name = "rj54n1cb0c", | 333 | .module_name = "rj54n1cb0c", |
334 | .priv = &rj54n1_priv, | ||
326 | }; | 335 | }; |
327 | 336 | ||
328 | static struct platform_device kfr2r09_camera = { | 337 | static struct platform_device kfr2r09_camera = { |
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 9099b6da995..507c77be476 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c | |||
@@ -432,23 +432,27 @@ static struct i2c_board_info migor_i2c_camera[] = { | |||
432 | 432 | ||
433 | static struct ov772x_camera_info ov7725_info = { | 433 | static struct ov772x_camera_info ov7725_info = { |
434 | .buswidth = SOCAM_DATAWIDTH_8, | 434 | .buswidth = SOCAM_DATAWIDTH_8, |
435 | .link = { | 435 | }; |
436 | .power = ov7725_power, | 436 | |
437 | .board_info = &migor_i2c_camera[0], | 437 | static struct soc_camera_link ov7725_link = { |
438 | .i2c_adapter_id = 0, | 438 | .power = ov7725_power, |
439 | .module_name = "ov772x", | 439 | .board_info = &migor_i2c_camera[0], |
440 | }, | 440 | .i2c_adapter_id = 0, |
441 | .module_name = "ov772x", | ||
442 | .priv = &ov7725_info, | ||
441 | }; | 443 | }; |
442 | 444 | ||
443 | static struct tw9910_video_info tw9910_info = { | 445 | static struct tw9910_video_info tw9910_info = { |
444 | .buswidth = SOCAM_DATAWIDTH_8, | 446 | .buswidth = SOCAM_DATAWIDTH_8, |
445 | .mpout = TW9910_MPO_FIELD, | 447 | .mpout = TW9910_MPO_FIELD, |
446 | .link = { | 448 | }; |
447 | .power = tw9910_power, | 449 | |
448 | .board_info = &migor_i2c_camera[1], | 450 | static struct soc_camera_link tw9910_link = { |
449 | .i2c_adapter_id = 0, | 451 | .power = tw9910_power, |
450 | .module_name = "tw9910", | 452 | .board_info = &migor_i2c_camera[1], |
451 | } | 453 | .i2c_adapter_id = 0, |
454 | .module_name = "tw9910", | ||
455 | .priv = &tw9910_info, | ||
452 | }; | 456 | }; |
453 | 457 | ||
454 | static struct platform_device migor_camera[] = { | 458 | static struct platform_device migor_camera[] = { |
@@ -456,13 +460,13 @@ static struct platform_device migor_camera[] = { | |||
456 | .name = "soc-camera-pdrv", | 460 | .name = "soc-camera-pdrv", |
457 | .id = 0, | 461 | .id = 0, |
458 | .dev = { | 462 | .dev = { |
459 | .platform_data = &ov7725_info.link, | 463 | .platform_data = &ov7725_link, |
460 | }, | 464 | }, |
461 | }, { | 465 | }, { |
462 | .name = "soc-camera-pdrv", | 466 | .name = "soc-camera-pdrv", |
463 | .id = 1, | 467 | .id = 1, |
464 | .dev = { | 468 | .dev = { |
465 | .platform_data = &tw9910_info.link, | 469 | .platform_data = &tw9910_link, |
466 | }, | 470 | }, |
467 | }, | 471 | }, |
468 | }; | 472 | }; |
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig new file mode 100644 index 00000000000..4dde7d180a3 --- /dev/null +++ b/drivers/media/IR/Kconfig | |||
@@ -0,0 +1,9 @@ | |||
1 | config IR_CORE | ||
2 | tristate | ||
3 | depends on INPUT | ||
4 | default INPUT | ||
5 | |||
6 | config VIDEO_IR | ||
7 | tristate | ||
8 | depends on IR_CORE | ||
9 | default IR_CORE | ||
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile new file mode 100644 index 00000000000..df5ddb4bbbf --- /dev/null +++ b/drivers/media/IR/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | ir-common-objs := ir-functions.o ir-keymaps.o | ||
2 | ir-core-objs := ir-keytable.o | ||
3 | |||
4 | obj-$(CONFIG_IR_CORE) += ir-core.o | ||
5 | obj-$(CONFIG_VIDEO_IR) += ir-common.o | ||
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/IR/ir-functions.c index e616f624cea..776a136616d 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/IR/ir-functions.c | |||
@@ -34,9 +34,6 @@ static int repeat = 1; | |||
34 | module_param(repeat, int, 0444); | 34 | module_param(repeat, int, 0444); |
35 | MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); | 35 | MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); |
36 | 36 | ||
37 | int media_ir_debug; /* media_ir_debug level (0,1,2) */ | ||
38 | module_param_named(debug, media_ir_debug, int, 0644); | ||
39 | |||
40 | /* -------------------------------------------------------------------------- */ | 37 | /* -------------------------------------------------------------------------- */ |
41 | 38 | ||
42 | static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) | 39 | static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) |
@@ -55,25 +52,10 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) | |||
55 | /* -------------------------------------------------------------------------- */ | 52 | /* -------------------------------------------------------------------------- */ |
56 | 53 | ||
57 | int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | 54 | int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, |
58 | int ir_type, struct ir_scancode_table *ir_codes) | 55 | int ir_type) |
59 | { | 56 | { |
60 | ir->ir_type = ir_type; | 57 | ir->ir_type = ir_type; |
61 | 58 | ||
62 | ir->keytable.size = ir_roundup_tablesize(ir_codes->size); | ||
63 | ir->keytable.scan = kzalloc(ir->keytable.size * | ||
64 | sizeof(struct ir_scancode), GFP_KERNEL); | ||
65 | if (!ir->keytable.scan) | ||
66 | return -ENOMEM; | ||
67 | |||
68 | IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", | ||
69 | ir->keytable.size, | ||
70 | ir->keytable.size * sizeof(ir->keytable.scan)); | ||
71 | |||
72 | ir_copy_table(&ir->keytable, ir_codes); | ||
73 | ir_set_keycode_table(dev, &ir->keytable); | ||
74 | |||
75 | clear_bit(0, dev->keybit); | ||
76 | set_bit(EV_KEY, dev->evbit); | ||
77 | if (repeat) | 59 | if (repeat) |
78 | set_bit(EV_REP, dev->evbit); | 60 | set_bit(EV_REP, dev->evbit); |
79 | 61 | ||
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/IR/ir-keymaps.c index 328c973a083..9bbe6b1e987 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/IR/ir-keymaps.c | |||
@@ -1847,76 +1847,6 @@ struct ir_scancode_table ir_codes_hauppauge_new_table = { | |||
1847 | }; | 1847 | }; |
1848 | EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table); | 1848 | EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table); |
1849 | 1849 | ||
1850 | /* | ||
1851 | * Hauppauge:the newer, gray remotes (seems there are multiple | ||
1852 | * slightly different versions), shipped with cx88+ivtv cards. | ||
1853 | * | ||
1854 | * This table contains the complete RC5 code, instead of just the data part | ||
1855 | */ | ||
1856 | static struct ir_scancode ir_codes_rc5_hauppauge_new[] = { | ||
1857 | /* Keys 0 to 9 */ | ||
1858 | { 0x1e00, KEY_0 }, | ||
1859 | { 0x1e01, KEY_1 }, | ||
1860 | { 0x1e02, KEY_2 }, | ||
1861 | { 0x1e03, KEY_3 }, | ||
1862 | { 0x1e04, KEY_4 }, | ||
1863 | { 0x1e05, KEY_5 }, | ||
1864 | { 0x1e06, KEY_6 }, | ||
1865 | { 0x1e07, KEY_7 }, | ||
1866 | { 0x1e08, KEY_8 }, | ||
1867 | { 0x1e09, KEY_9 }, | ||
1868 | |||
1869 | { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ | ||
1870 | { 0x1e0b, KEY_RED }, /* red button */ | ||
1871 | { 0x1e0c, KEY_RADIO }, | ||
1872 | { 0x1e0d, KEY_MENU }, | ||
1873 | { 0x1e0e, KEY_SUBTITLE }, /* also the # key */ | ||
1874 | { 0x1e0f, KEY_MUTE }, | ||
1875 | { 0x1e10, KEY_VOLUMEUP }, | ||
1876 | { 0x1e11, KEY_VOLUMEDOWN }, | ||
1877 | { 0x1e12, KEY_PREVIOUS }, /* previous channel */ | ||
1878 | { 0x1e14, KEY_UP }, | ||
1879 | { 0x1e15, KEY_DOWN }, | ||
1880 | { 0x1e16, KEY_LEFT }, | ||
1881 | { 0x1e17, KEY_RIGHT }, | ||
1882 | { 0x1e18, KEY_VIDEO }, /* Videos */ | ||
1883 | { 0x1e19, KEY_AUDIO }, /* Music */ | ||
1884 | /* 0x1e1a: Pictures - presume this means | ||
1885 | "Multimedia Home Platform" - | ||
1886 | no "PICTURES" key in input.h | ||
1887 | */ | ||
1888 | { 0x1e1a, KEY_MHP }, | ||
1889 | |||
1890 | { 0x1e1b, KEY_EPG }, /* Guide */ | ||
1891 | { 0x1e1c, KEY_TV }, | ||
1892 | { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ | ||
1893 | { 0x1e1f, KEY_EXIT }, /* back/exit */ | ||
1894 | { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ | ||
1895 | { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ | ||
1896 | { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */ | ||
1897 | { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ | ||
1898 | { 0x1e25, KEY_ENTER }, /* OK */ | ||
1899 | { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */ | ||
1900 | { 0x1e29, KEY_BLUE }, /* blue key */ | ||
1901 | { 0x1e2e, KEY_GREEN }, /* green button */ | ||
1902 | { 0x1e30, KEY_PAUSE }, /* pause */ | ||
1903 | { 0x1e32, KEY_REWIND }, /* backward << */ | ||
1904 | { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ | ||
1905 | { 0x1e35, KEY_PLAY }, | ||
1906 | { 0x1e36, KEY_STOP }, | ||
1907 | { 0x1e37, KEY_RECORD }, /* recording */ | ||
1908 | { 0x1e38, KEY_YELLOW }, /* yellow key */ | ||
1909 | { 0x1e3b, KEY_SELECT }, /* top right button */ | ||
1910 | { 0x1e3c, KEY_ZOOM }, /* full */ | ||
1911 | { 0x1e3d, KEY_POWER }, /* system power (green button) */ | ||
1912 | }; | ||
1913 | |||
1914 | struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = { | ||
1915 | .scan = ir_codes_rc5_hauppauge_new, | ||
1916 | .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new), | ||
1917 | }; | ||
1918 | EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table); | ||
1919 | |||
1920 | static struct ir_scancode ir_codes_npgtech[] = { | 1850 | static struct ir_scancode ir_codes_npgtech[] = { |
1921 | { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ | 1851 | { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ |
1922 | { 0x2a, KEY_FRONT }, | 1852 | { 0x2a, KEY_FRONT }, |
@@ -3314,3 +3244,152 @@ struct ir_scancode_table ir_codes_gadmei_rm008z_table = { | |||
3314 | }; | 3244 | }; |
3315 | EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table); | 3245 | EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table); |
3316 | 3246 | ||
3247 | /************************************************************* | ||
3248 | * COMPLETE SCANCODE TABLES | ||
3249 | * Instead of just a partial scancode, the tables bellow | ||
3250 | * contains the complete scancode and the receiver protocol | ||
3251 | *************************************************************/ | ||
3252 | |||
3253 | /* | ||
3254 | * Hauppauge:the newer, gray remotes (seems there are multiple | ||
3255 | * slightly different versions), shipped with cx88+ivtv cards. | ||
3256 | * | ||
3257 | * This table contains the complete RC5 code, instead of just the data part | ||
3258 | */ | ||
3259 | static struct ir_scancode ir_codes_rc5_hauppauge_new[] = { | ||
3260 | /* Keys 0 to 9 */ | ||
3261 | { 0x1e00, KEY_0 }, | ||
3262 | { 0x1e01, KEY_1 }, | ||
3263 | { 0x1e02, KEY_2 }, | ||
3264 | { 0x1e03, KEY_3 }, | ||
3265 | { 0x1e04, KEY_4 }, | ||
3266 | { 0x1e05, KEY_5 }, | ||
3267 | { 0x1e06, KEY_6 }, | ||
3268 | { 0x1e07, KEY_7 }, | ||
3269 | { 0x1e08, KEY_8 }, | ||
3270 | { 0x1e09, KEY_9 }, | ||
3271 | |||
3272 | { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ | ||
3273 | { 0x1e0b, KEY_RED }, /* red button */ | ||
3274 | { 0x1e0c, KEY_RADIO }, | ||
3275 | { 0x1e0d, KEY_MENU }, | ||
3276 | { 0x1e0e, KEY_SUBTITLE }, /* also the # key */ | ||
3277 | { 0x1e0f, KEY_MUTE }, | ||
3278 | { 0x1e10, KEY_VOLUMEUP }, | ||
3279 | { 0x1e11, KEY_VOLUMEDOWN }, | ||
3280 | { 0x1e12, KEY_PREVIOUS }, /* previous channel */ | ||
3281 | { 0x1e14, KEY_UP }, | ||
3282 | { 0x1e15, KEY_DOWN }, | ||
3283 | { 0x1e16, KEY_LEFT }, | ||
3284 | { 0x1e17, KEY_RIGHT }, | ||
3285 | { 0x1e18, KEY_VIDEO }, /* Videos */ | ||
3286 | { 0x1e19, KEY_AUDIO }, /* Music */ | ||
3287 | /* 0x1e1a: Pictures - presume this means | ||
3288 | "Multimedia Home Platform" - | ||
3289 | no "PICTURES" key in input.h | ||
3290 | */ | ||
3291 | { 0x1e1a, KEY_MHP }, | ||
3292 | |||
3293 | { 0x1e1b, KEY_EPG }, /* Guide */ | ||
3294 | { 0x1e1c, KEY_TV }, | ||
3295 | { 0x1e1e, KEY_NEXTSONG }, /* skip >| */ | ||
3296 | { 0x1e1f, KEY_EXIT }, /* back/exit */ | ||
3297 | { 0x1e20, KEY_CHANNELUP }, /* channel / program + */ | ||
3298 | { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */ | ||
3299 | { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */ | ||
3300 | { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */ | ||
3301 | { 0x1e25, KEY_ENTER }, /* OK */ | ||
3302 | { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */ | ||
3303 | { 0x1e29, KEY_BLUE }, /* blue key */ | ||
3304 | { 0x1e2e, KEY_GREEN }, /* green button */ | ||
3305 | { 0x1e30, KEY_PAUSE }, /* pause */ | ||
3306 | { 0x1e32, KEY_REWIND }, /* backward << */ | ||
3307 | { 0x1e34, KEY_FASTFORWARD }, /* forward >> */ | ||
3308 | { 0x1e35, KEY_PLAY }, | ||
3309 | { 0x1e36, KEY_STOP }, | ||
3310 | { 0x1e37, KEY_RECORD }, /* recording */ | ||
3311 | { 0x1e38, KEY_YELLOW }, /* yellow key */ | ||
3312 | { 0x1e3b, KEY_SELECT }, /* top right button */ | ||
3313 | { 0x1e3c, KEY_ZOOM }, /* full */ | ||
3314 | { 0x1e3d, KEY_POWER }, /* system power (green button) */ | ||
3315 | }; | ||
3316 | |||
3317 | struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = { | ||
3318 | .scan = ir_codes_rc5_hauppauge_new, | ||
3319 | .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new), | ||
3320 | .ir_type = IR_TYPE_RC5, | ||
3321 | }; | ||
3322 | EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table); | ||
3323 | |||
3324 | /* Terratec Cinergy Hybrid T USB XS FM | ||
3325 | Mauro Carvalho Chehab <mchehab@redhat.com> | ||
3326 | */ | ||
3327 | static struct ir_scancode ir_codes_nec_terratec_cinergy_xs[] = { | ||
3328 | { 0x1441, KEY_HOME}, | ||
3329 | { 0x1401, KEY_POWER2}, | ||
3330 | |||
3331 | { 0x1442, KEY_MENU}, /* DVD menu */ | ||
3332 | { 0x1443, KEY_SUBTITLE}, | ||
3333 | { 0x1444, KEY_TEXT}, /* Teletext */ | ||
3334 | { 0x1445, KEY_DELETE}, | ||
3335 | |||
3336 | { 0x1402, KEY_1}, | ||
3337 | { 0x1403, KEY_2}, | ||
3338 | { 0x1404, KEY_3}, | ||
3339 | { 0x1405, KEY_4}, | ||
3340 | { 0x1406, KEY_5}, | ||
3341 | { 0x1407, KEY_6}, | ||
3342 | { 0x1408, KEY_7}, | ||
3343 | { 0x1409, KEY_8}, | ||
3344 | { 0x140a, KEY_9}, | ||
3345 | { 0x140c, KEY_0}, | ||
3346 | |||
3347 | { 0x140b, KEY_TUNER}, /* AV */ | ||
3348 | { 0x140d, KEY_MODE}, /* A.B */ | ||
3349 | |||
3350 | { 0x1446, KEY_TV}, | ||
3351 | { 0x1447, KEY_DVD}, | ||
3352 | { 0x1449, KEY_VIDEO}, | ||
3353 | { 0x144a, KEY_RADIO}, /* Music */ | ||
3354 | { 0x144b, KEY_CAMERA}, /* PIC */ | ||
3355 | |||
3356 | { 0x1410, KEY_UP}, | ||
3357 | { 0x1411, KEY_LEFT}, | ||
3358 | { 0x1412, KEY_OK}, | ||
3359 | { 0x1413, KEY_RIGHT}, | ||
3360 | { 0x1414, KEY_DOWN}, | ||
3361 | |||
3362 | { 0x140f, KEY_EPG}, | ||
3363 | { 0x1416, KEY_INFO}, | ||
3364 | { 0x144d, KEY_BACKSPACE}, | ||
3365 | |||
3366 | { 0x141c, KEY_VOLUMEUP}, | ||
3367 | { 0x141e, KEY_VOLUMEDOWN}, | ||
3368 | |||
3369 | { 0x144c, KEY_PLAY}, | ||
3370 | { 0x141d, KEY_MUTE}, | ||
3371 | |||
3372 | { 0x141b, KEY_CHANNELUP}, | ||
3373 | { 0x141f, KEY_CHANNELDOWN}, | ||
3374 | |||
3375 | { 0x1417, KEY_RED}, | ||
3376 | { 0x1418, KEY_GREEN}, | ||
3377 | { 0x1419, KEY_YELLOW}, | ||
3378 | { 0x141a, KEY_BLUE}, | ||
3379 | |||
3380 | { 0x1458, KEY_RECORD}, | ||
3381 | { 0x1448, KEY_STOP}, | ||
3382 | { 0x1440, KEY_PAUSE}, | ||
3383 | |||
3384 | { 0x1454, KEY_LAST}, | ||
3385 | { 0x144e, KEY_REWIND}, | ||
3386 | { 0x144f, KEY_FASTFORWARD}, | ||
3387 | { 0x145c, KEY_NEXT}, | ||
3388 | }; | ||
3389 | struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table = { | ||
3390 | .scan = ir_codes_nec_terratec_cinergy_xs, | ||
3391 | .size = ARRAY_SIZE(ir_codes_nec_terratec_cinergy_xs), | ||
3392 | .ir_type = IR_TYPE_NEC, | ||
3393 | }; | ||
3394 | EXPORT_SYMBOL_GPL(ir_codes_nec_terratec_cinergy_xs_table); | ||
3395 | |||
diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 26ce5bc2fdd..bff7a535603 100644 --- a/drivers/media/common/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -1,10 +1,19 @@ | |||
1 | /* ir-register.c - handle IR scancode->keycode tables | 1 | /* ir-register.c - handle IR scancode->keycode tables |
2 | * | 2 | * |
3 | * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com> | 3 | * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com> |
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation version 2 of the License. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
4 | */ | 13 | */ |
5 | 14 | ||
6 | #include <linux/usb/input.h> | ||
7 | 15 | ||
16 | #include <linux/usb/input.h> | ||
8 | #include <media/ir-common.h> | 17 | #include <media/ir-common.h> |
9 | 18 | ||
10 | #define IR_TAB_MIN_SIZE 32 | 19 | #define IR_TAB_MIN_SIZE 32 |
@@ -72,6 +81,7 @@ int ir_roundup_tablesize(int n_elems) | |||
72 | 81 | ||
73 | return n_elems; | 82 | return n_elems; |
74 | } | 83 | } |
84 | EXPORT_SYMBOL_GPL(ir_roundup_tablesize); | ||
75 | 85 | ||
76 | /** | 86 | /** |
77 | * ir_copy_table() - copies a keytable, discarding the unused entries | 87 | * ir_copy_table() - copies a keytable, discarding the unused entries |
@@ -100,6 +110,7 @@ int ir_copy_table(struct ir_scancode_table *destin, | |||
100 | 110 | ||
101 | return 0; | 111 | return 0; |
102 | } | 112 | } |
113 | EXPORT_SYMBOL_GPL(ir_copy_table); | ||
103 | 114 | ||
104 | /** | 115 | /** |
105 | * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table | 116 | * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table |
@@ -114,7 +125,8 @@ static int ir_getkeycode(struct input_dev *dev, | |||
114 | int scancode, int *keycode) | 125 | int scancode, int *keycode) |
115 | { | 126 | { |
116 | int elem; | 127 | int elem; |
117 | struct ir_scancode_table *rc_tab = input_get_drvdata(dev); | 128 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
129 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | ||
118 | 130 | ||
119 | elem = ir_seek_table(rc_tab, scancode); | 131 | elem = ir_seek_table(rc_tab, scancode); |
120 | if (elem >= 0) { | 132 | if (elem >= 0) { |
@@ -136,7 +148,6 @@ static int ir_getkeycode(struct input_dev *dev, | |||
136 | return 0; | 148 | return 0; |
137 | } | 149 | } |
138 | 150 | ||
139 | |||
140 | /** | 151 | /** |
141 | * ir_is_resize_needed() - Check if the table needs rezise | 152 | * ir_is_resize_needed() - Check if the table needs rezise |
142 | * @table: keycode table that may need to resize | 153 | * @table: keycode table that may need to resize |
@@ -286,7 +297,8 @@ static int ir_setkeycode(struct input_dev *dev, | |||
286 | int scancode, int keycode) | 297 | int scancode, int keycode) |
287 | { | 298 | { |
288 | int rc = 0; | 299 | int rc = 0; |
289 | struct ir_scancode_table *rc_tab = input_get_drvdata(dev); | 300 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
301 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | ||
290 | struct ir_scancode *keymap = rc_tab->scan; | 302 | struct ir_scancode *keymap = rc_tab->scan; |
291 | unsigned long flags; | 303 | unsigned long flags; |
292 | 304 | ||
@@ -360,7 +372,8 @@ static int ir_setkeycode(struct input_dev *dev, | |||
360 | */ | 372 | */ |
361 | u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) | 373 | u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) |
362 | { | 374 | { |
363 | struct ir_scancode_table *rc_tab = input_get_drvdata(dev); | 375 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
376 | struct ir_scancode_table *rc_tab = &ir_dev->rc_tab; | ||
364 | struct ir_scancode *keymap = rc_tab->scan; | 377 | struct ir_scancode *keymap = rc_tab->scan; |
365 | int elem; | 378 | int elem; |
366 | 379 | ||
@@ -378,9 +391,10 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) | |||
378 | /* Reports userspace that an unknown keycode were got */ | 391 | /* Reports userspace that an unknown keycode were got */ |
379 | return KEY_RESERVED; | 392 | return KEY_RESERVED; |
380 | } | 393 | } |
394 | EXPORT_SYMBOL_GPL(ir_g_keycode_from_table); | ||
381 | 395 | ||
382 | /** | 396 | /** |
383 | * ir_set_keycode_table() - sets the IR keycode table and add the handlers | 397 | * ir_input_register() - sets the IR keycode table and add the handlers |
384 | * for keymap table get/set | 398 | * for keymap table get/set |
385 | * @input_dev: the struct input_dev descriptor of the device | 399 | * @input_dev: the struct input_dev descriptor of the device |
386 | * @rc_tab: the struct ir_scancode_table table of scancode/keymap | 400 | * @rc_tab: the struct ir_scancode_table table of scancode/keymap |
@@ -389,17 +403,34 @@ u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode) | |||
389 | * an IR. | 403 | * an IR. |
390 | * It should be called before registering the IR device. | 404 | * It should be called before registering the IR device. |
391 | */ | 405 | */ |
392 | int ir_set_keycode_table(struct input_dev *input_dev, | 406 | int ir_input_register(struct input_dev *input_dev, |
393 | struct ir_scancode_table *rc_tab) | 407 | struct ir_scancode_table *rc_tab) |
394 | { | 408 | { |
395 | struct ir_scancode *keymap = rc_tab->scan; | 409 | struct ir_input_dev *ir_dev; |
396 | int i; | 410 | struct ir_scancode *keymap = rc_tab->scan; |
397 | 411 | int i, rc; | |
398 | spin_lock_init(&rc_tab->lock); | ||
399 | 412 | ||
400 | if (rc_tab->scan == NULL || !rc_tab->size) | 413 | if (rc_tab->scan == NULL || !rc_tab->size) |
401 | return -EINVAL; | 414 | return -EINVAL; |
402 | 415 | ||
416 | ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); | ||
417 | if (!ir_dev) | ||
418 | return -ENOMEM; | ||
419 | |||
420 | spin_lock_init(&rc_tab->lock); | ||
421 | |||
422 | ir_dev->rc_tab.size = ir_roundup_tablesize(rc_tab->size); | ||
423 | ir_dev->rc_tab.scan = kzalloc(ir_dev->rc_tab.size * | ||
424 | sizeof(struct ir_scancode), GFP_KERNEL); | ||
425 | if (!ir_dev->rc_tab.scan) | ||
426 | return -ENOMEM; | ||
427 | |||
428 | IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n", | ||
429 | ir_dev->rc_tab.size, | ||
430 | ir_dev->rc_tab.size * sizeof(ir_dev->rc_tab.scan)); | ||
431 | |||
432 | ir_copy_table(&ir_dev->rc_tab, rc_tab); | ||
433 | |||
403 | /* set the bits for the keys */ | 434 | /* set the bits for the keys */ |
404 | IR_dprintk(1, "key map size: %d\n", rc_tab->size); | 435 | IR_dprintk(1, "key map size: %d\n", rc_tab->size); |
405 | for (i = 0; i < rc_tab->size; i++) { | 436 | for (i = 0; i < rc_tab->size; i++) { |
@@ -407,23 +438,48 @@ int ir_set_keycode_table(struct input_dev *input_dev, | |||
407 | i, keymap[i].keycode); | 438 | i, keymap[i].keycode); |
408 | set_bit(keymap[i].keycode, input_dev->keybit); | 439 | set_bit(keymap[i].keycode, input_dev->keybit); |
409 | } | 440 | } |
441 | clear_bit(0, input_dev->keybit); | ||
442 | |||
443 | set_bit(EV_KEY, input_dev->evbit); | ||
410 | 444 | ||
411 | input_dev->getkeycode = ir_getkeycode; | 445 | input_dev->getkeycode = ir_getkeycode; |
412 | input_dev->setkeycode = ir_setkeycode; | 446 | input_dev->setkeycode = ir_setkeycode; |
413 | input_set_drvdata(input_dev, rc_tab); | 447 | input_set_drvdata(input_dev, ir_dev); |
414 | 448 | ||
415 | return 0; | 449 | rc = input_register_device(input_dev); |
450 | if (rc < 0) { | ||
451 | kfree(rc_tab->scan); | ||
452 | kfree(ir_dev); | ||
453 | input_set_drvdata(input_dev, NULL); | ||
454 | } | ||
455 | |||
456 | return rc; | ||
416 | } | 457 | } |
458 | EXPORT_SYMBOL_GPL(ir_input_register); | ||
417 | 459 | ||
418 | void ir_input_free(struct input_dev *dev) | 460 | void ir_input_unregister(struct input_dev *dev) |
419 | { | 461 | { |
420 | struct ir_scancode_table *rc_tab = input_get_drvdata(dev); | 462 | struct ir_input_dev *ir_dev = input_get_drvdata(dev); |
463 | struct ir_scancode_table *rc_tab; | ||
464 | |||
465 | if (!ir_dev) | ||
466 | return; | ||
421 | 467 | ||
422 | IR_dprintk(1, "Freed keycode table\n"); | 468 | IR_dprintk(1, "Freed keycode table\n"); |
423 | 469 | ||
470 | rc_tab = &ir_dev->rc_tab; | ||
424 | rc_tab->size = 0; | 471 | rc_tab->size = 0; |
425 | kfree(rc_tab->scan); | 472 | kfree(rc_tab->scan); |
426 | rc_tab->scan = NULL; | 473 | rc_tab->scan = NULL; |
474 | |||
475 | kfree(ir_dev); | ||
476 | input_unregister_device(dev); | ||
427 | } | 477 | } |
428 | EXPORT_SYMBOL_GPL(ir_input_free); | 478 | EXPORT_SYMBOL_GPL(ir_input_unregister); |
479 | |||
480 | int ir_core_debug; /* ir_debug level (0,1,2) */ | ||
481 | EXPORT_SYMBOL_GPL(ir_core_debug); | ||
482 | module_param_named(debug, ir_core_debug, int, 0644); | ||
429 | 483 | ||
484 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | ||
485 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index ba69beeb0e2..a28541b2b1a 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
@@ -99,6 +99,7 @@ config VIDEO_MEDIA | |||
99 | comment "Multimedia drivers" | 99 | comment "Multimedia drivers" |
100 | 100 | ||
101 | source "drivers/media/common/Kconfig" | 101 | source "drivers/media/common/Kconfig" |
102 | source "drivers/media/IR/Kconfig" | ||
102 | 103 | ||
103 | # | 104 | # |
104 | # Tuner drivers for DVB and V4L | 105 | # Tuner drivers for DVB and V4L |
diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 09a829d8a7e..499b0810d01 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the kernel multimedia device drivers. | 2 | # Makefile for the kernel multimedia device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += common/ video/ | 5 | obj-y += common/ IR/ video/ |
6 | 6 | ||
7 | obj-$(CONFIG_VIDEO_DEV) += radio/ | 7 | obj-$(CONFIG_VIDEO_DEV) += radio/ |
8 | obj-$(CONFIG_DVB_CORE) += dvb/ | 8 | obj-$(CONFIG_DVB_CORE) += dvb/ |
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile index 169b337b7c9..e3ec9639321 100644 --- a/drivers/media/common/Makefile +++ b/drivers/media/common/Makefile | |||
@@ -1,8 +1,6 @@ | |||
1 | saa7146-objs := saa7146_i2c.o saa7146_core.o | 1 | saa7146-objs := saa7146_i2c.o saa7146_core.o |
2 | saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o | 2 | saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o |
3 | ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o | ||
4 | 3 | ||
5 | obj-y += tuners/ | 4 | obj-y += tuners/ |
6 | obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o | 5 | obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o |
7 | obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o | 6 | obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o |
8 | obj-$(CONFIG_VIDEO_IR) += ir-common.o | ||
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 620f655fa9c..7364b9642d0 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
@@ -1,7 +1,5 @@ | |||
1 | #include <media/saa7146_vv.h> | 1 | #include <media/saa7146_vv.h> |
2 | 2 | ||
3 | #define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1) | ||
4 | |||
5 | /****************************************************************************/ | 3 | /****************************************************************************/ |
6 | /* resource management functions, shamelessly stolen from saa7134 driver */ | 4 | /* resource management functions, shamelessly stolen from saa7134 driver */ |
7 | 5 | ||
@@ -194,43 +192,24 @@ void saa7146_buffer_timeout(unsigned long data) | |||
194 | 192 | ||
195 | static int fops_open(struct file *file) | 193 | static int fops_open(struct file *file) |
196 | { | 194 | { |
197 | unsigned int minor = video_devdata(file)->minor; | 195 | struct video_device *vdev = video_devdata(file); |
198 | struct saa7146_dev *h = NULL, *dev = NULL; | 196 | struct saa7146_dev *dev = video_drvdata(file); |
199 | struct list_head *list; | ||
200 | struct saa7146_fh *fh = NULL; | 197 | struct saa7146_fh *fh = NULL; |
201 | int result = 0; | 198 | int result = 0; |
202 | 199 | ||
203 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 200 | enum v4l2_buf_type type; |
204 | 201 | ||
205 | DEB_EE(("file:%p, minor:%d\n", file, minor)); | 202 | DEB_EE(("file:%p, dev:%s\n", file, video_device_node_name(vdev))); |
206 | 203 | ||
207 | if (mutex_lock_interruptible(&saa7146_devices_lock)) | 204 | if (mutex_lock_interruptible(&saa7146_devices_lock)) |
208 | return -ERESTARTSYS; | 205 | return -ERESTARTSYS; |
209 | 206 | ||
210 | list_for_each(list,&saa7146_devices) { | ||
211 | h = list_entry(list, struct saa7146_dev, item); | ||
212 | if( NULL == h->vv_data ) { | ||
213 | DEB_D(("device %p has not registered video devices.\n",h)); | ||
214 | continue; | ||
215 | } | ||
216 | DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor)); | ||
217 | |||
218 | if (h->vv_data->video_minor == minor) { | ||
219 | dev = h; | ||
220 | } | ||
221 | if (h->vv_data->vbi_minor == minor) { | ||
222 | type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
223 | dev = h; | ||
224 | } | ||
225 | } | ||
226 | if (NULL == dev) { | ||
227 | DEB_S(("no such video device.\n")); | ||
228 | result = -ENODEV; | ||
229 | goto out; | ||
230 | } | ||
231 | |||
232 | DEB_D(("using: %p\n",dev)); | 207 | DEB_D(("using: %p\n",dev)); |
233 | 208 | ||
209 | type = vdev->vfl_type == VFL_TYPE_GRABBER | ||
210 | ? V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
211 | : V4L2_BUF_TYPE_VBI_CAPTURE; | ||
212 | |||
234 | /* check if an extension is registered */ | 213 | /* check if an extension is registered */ |
235 | if( NULL == dev->ext ) { | 214 | if( NULL == dev->ext ) { |
236 | DEB_S(("no extension registered for this device.\n")); | 215 | DEB_S(("no extension registered for this device.\n")); |
@@ -474,9 +453,6 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) | |||
474 | configuration data) */ | 453 | configuration data) */ |
475 | dev->ext_vv_data = ext_vv; | 454 | dev->ext_vv_data = ext_vv; |
476 | 455 | ||
477 | vv->video_minor = -1; | ||
478 | vv->vbi_minor = -1; | ||
479 | |||
480 | vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle); | 456 | vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle); |
481 | if( NULL == vv->d_clipping.cpu_addr ) { | 457 | if( NULL == vv->d_clipping.cpu_addr ) { |
482 | ERR(("out of memory. aborting.\n")); | 458 | ERR(("out of memory. aborting.\n")); |
@@ -515,7 +491,6 @@ EXPORT_SYMBOL_GPL(saa7146_vv_release); | |||
515 | int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | 491 | int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, |
516 | char *name, int type) | 492 | char *name, int type) |
517 | { | 493 | { |
518 | struct saa7146_vv *vv = dev->vv_data; | ||
519 | struct video_device *vfd; | 494 | struct video_device *vfd; |
520 | int err; | 495 | int err; |
521 | int i; | 496 | int i; |
@@ -543,15 +518,8 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | |||
543 | return err; | 518 | return err; |
544 | } | 519 | } |
545 | 520 | ||
546 | if( VFL_TYPE_GRABBER == type ) { | 521 | INFO(("%s: registered device %s [v4l2]\n", |
547 | vv->video_minor = vfd->minor; | 522 | dev->name, video_device_node_name(vfd))); |
548 | INFO(("%s: registered device video%d [v4l2]\n", | ||
549 | dev->name, vfd->num)); | ||
550 | } else { | ||
551 | vv->vbi_minor = vfd->minor; | ||
552 | INFO(("%s: registered device vbi%d [v4l2]\n", | ||
553 | dev->name, vfd->num)); | ||
554 | } | ||
555 | 523 | ||
556 | *vid = vfd; | 524 | *vid = vfd; |
557 | return 0; | 525 | return 0; |
@@ -560,16 +528,8 @@ EXPORT_SYMBOL_GPL(saa7146_register_device); | |||
560 | 528 | ||
561 | int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) | 529 | int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) |
562 | { | 530 | { |
563 | struct saa7146_vv *vv = dev->vv_data; | ||
564 | |||
565 | DEB_EE(("dev:%p\n",dev)); | 531 | DEB_EE(("dev:%p\n",dev)); |
566 | 532 | ||
567 | if ((*vid)->vfl_type == VFL_TYPE_GRABBER) { | ||
568 | vv->video_minor = -1; | ||
569 | } else { | ||
570 | vv->vbi_minor = -1; | ||
571 | } | ||
572 | |||
573 | video_unregister_device(*vid); | 533 | video_unregister_device(*vid); |
574 | *vid = NULL; | 534 | *vid = NULL; |
575 | 535 | ||
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 53e3f2a7d31..f0f483ac8b8 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c | |||
@@ -589,7 +589,7 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) | |||
589 | snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), | 589 | snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), |
590 | "pci-%s/ir0", pci_name(dm1105->pdev)); | 590 | "pci-%s/ir0", pci_name(dm1105->pdev)); |
591 | 591 | ||
592 | err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes); | 592 | err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type); |
593 | if (err < 0) { | 593 | if (err < 0) { |
594 | input_free_device(input_dev); | 594 | input_free_device(input_dev); |
595 | return err; | 595 | return err; |
@@ -611,20 +611,14 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) | |||
611 | 611 | ||
612 | INIT_WORK(&dm1105->ir.work, dm1105_emit_key); | 612 | INIT_WORK(&dm1105->ir.work, dm1105_emit_key); |
613 | 613 | ||
614 | err = input_register_device(input_dev); | 614 | err = ir_input_register(input_dev, ir_codes); |
615 | if (err) { | ||
616 | ir_input_free(input_dev); | ||
617 | input_free_device(input_dev); | ||
618 | return err; | ||
619 | } | ||
620 | 615 | ||
621 | return 0; | 616 | return err; |
622 | } | 617 | } |
623 | 618 | ||
624 | void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) | 619 | void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) |
625 | { | 620 | { |
626 | ir_input_free(dm1105->ir.input_dev); | 621 | ir_input_unregister(dm1105->ir.input_dev); |
627 | input_unregister_device(dm1105->ir.input_dev); | ||
628 | } | 622 | } |
629 | 623 | ||
630 | static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb) | 624 | static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb) |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 2dee1bf7357..1b249897c9f 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -265,9 +265,13 @@ config DVB_USB_DW2102 | |||
265 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | 265 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE |
266 | select DVB_MT312 if !DVB_FE_CUSTOMISE | 266 | select DVB_MT312 if !DVB_FE_CUSTOMISE |
267 | select DVB_ZL10039 if !DVB_FE_CUSTOMISE | 267 | select DVB_ZL10039 if !DVB_FE_CUSTOMISE |
268 | select DVB_DS3000 if !DVB_FE_CUSTOMISE | ||
269 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | ||
270 | select DVB_STV6110 if !DVB_FE_CUSTOMISE | ||
271 | select DVB_STV0900 if !DVB_FE_CUSTOMISE | ||
268 | help | 272 | help |
269 | Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers | 273 | Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0 |
270 | and the TeVii S650, S630. | 274 | receivers. |
271 | 275 | ||
272 | config DVB_USB_CINERGY_T2 | 276 | config DVB_USB_CINERGY_T2 |
273 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" | 277 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" |
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 8b544fe79b0..495a90577c5 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h | |||
@@ -20,20 +20,22 @@ extern int dvb_usb_dib0700_debug; | |||
20 | #define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args) | 20 | #define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args) |
21 | #define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args) | 21 | #define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args) |
22 | 22 | ||
23 | #define REQUEST_I2C_READ 0x2 | 23 | #define REQUEST_SET_USB_XFER_LEN 0x0 /* valid only for firmware version */ |
24 | #define REQUEST_I2C_WRITE 0x3 | 24 | /* higher than 1.21 */ |
25 | #define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */ | 25 | #define REQUEST_I2C_READ 0x2 |
26 | #define REQUEST_JUMPRAM 0x8 | 26 | #define REQUEST_I2C_WRITE 0x3 |
27 | #define REQUEST_SET_CLOCK 0xB | 27 | #define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */ |
28 | #define REQUEST_SET_GPIO 0xC | 28 | #define REQUEST_JUMPRAM 0x8 |
29 | #define REQUEST_ENABLE_VIDEO 0xF | 29 | #define REQUEST_SET_CLOCK 0xB |
30 | #define REQUEST_SET_GPIO 0xC | ||
31 | #define REQUEST_ENABLE_VIDEO 0xF | ||
30 | // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) | 32 | // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) |
31 | // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) | 33 | // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) |
32 | // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) | 34 | // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) |
33 | #define REQUEST_SET_RC 0x11 | 35 | #define REQUEST_SET_RC 0x11 |
34 | #define REQUEST_NEW_I2C_READ 0x12 | 36 | #define REQUEST_NEW_I2C_READ 0x12 |
35 | #define REQUEST_NEW_I2C_WRITE 0x13 | 37 | #define REQUEST_NEW_I2C_WRITE 0x13 |
36 | #define REQUEST_GET_VERSION 0x15 | 38 | #define REQUEST_GET_VERSION 0x15 |
37 | 39 | ||
38 | struct dib0700_state { | 40 | struct dib0700_state { |
39 | u8 channel_state; | 41 | u8 channel_state; |
@@ -44,6 +46,8 @@ struct dib0700_state { | |||
44 | u8 is_dib7000pc; | 46 | u8 is_dib7000pc; |
45 | u8 fw_use_new_i2c_api; | 47 | u8 fw_use_new_i2c_api; |
46 | u8 disable_streaming_master_mode; | 48 | u8 disable_streaming_master_mode; |
49 | u32 fw_version; | ||
50 | u32 nb_packet_buffer_size; | ||
47 | }; | 51 | }; |
48 | 52 | ||
49 | extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, | 53 | extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index db7f7f79a66..0d3c9a9a33b 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
@@ -17,6 +17,14 @@ int dvb_usb_dib0700_ir_proto = 1; | |||
17 | module_param(dvb_usb_dib0700_ir_proto, int, 0644); | 17 | module_param(dvb_usb_dib0700_ir_proto, int, 0644); |
18 | MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6)."); | 18 | MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6)."); |
19 | 19 | ||
20 | static int nb_packet_buffer_size = 21; | ||
21 | module_param(nb_packet_buffer_size, int, 0644); | ||
22 | MODULE_PARM_DESC(nb_packet_buffer_size, | ||
23 | "Set the dib0700 driver data buffer size. This parameter " | ||
24 | "corresponds to the number of TS packets. The actual size of " | ||
25 | "the data buffer corresponds to this parameter " | ||
26 | "multiplied by 188 (default: 21)"); | ||
27 | |||
20 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 28 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
21 | 29 | ||
22 | 30 | ||
@@ -28,10 +36,14 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, | |||
28 | REQUEST_GET_VERSION, | 36 | REQUEST_GET_VERSION, |
29 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, | 37 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, |
30 | b, sizeof(b), USB_CTRL_GET_TIMEOUT); | 38 | b, sizeof(b), USB_CTRL_GET_TIMEOUT); |
31 | *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; | 39 | if (hwversion != NULL) |
32 | *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; | 40 | *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; |
33 | *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; | 41 | if (romversion != NULL) |
34 | *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; | 42 | *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; |
43 | if (ramversion != NULL) | ||
44 | *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; | ||
45 | if (fwtype != NULL) | ||
46 | *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; | ||
35 | return ret; | 47 | return ret; |
36 | } | 48 | } |
37 | 49 | ||
@@ -97,6 +109,27 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_ | |||
97 | return dib0700_ctrl_wr(d,buf,3); | 109 | return dib0700_ctrl_wr(d,buf,3); |
98 | } | 110 | } |
99 | 111 | ||
112 | static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets) | ||
113 | { | ||
114 | struct dib0700_state *st = d->priv; | ||
115 | u8 b[3]; | ||
116 | int ret; | ||
117 | |||
118 | if (st->fw_version >= 0x10201) { | ||
119 | b[0] = REQUEST_SET_USB_XFER_LEN; | ||
120 | b[1] = (nb_ts_packets >> 8)&0xff; | ||
121 | b[2] = nb_ts_packets & 0xff; | ||
122 | |||
123 | deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets); | ||
124 | |||
125 | ret = dib0700_ctrl_wr(d, b, 3); | ||
126 | } else { | ||
127 | deb_info("this firmware does not allow to change the USB xfer len\n"); | ||
128 | ret = -EIO; | ||
129 | } | ||
130 | return ret; | ||
131 | } | ||
132 | |||
100 | /* | 133 | /* |
101 | * I2C master xfer function (supported in 1.20 firmware) | 134 | * I2C master xfer function (supported in 1.20 firmware) |
102 | */ | 135 | */ |
@@ -328,7 +361,9 @@ static int dib0700_jumpram(struct usb_device *udev, u32 address) | |||
328 | int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw) | 361 | int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw) |
329 | { | 362 | { |
330 | struct hexline hx; | 363 | struct hexline hx; |
331 | int pos = 0, ret, act_len; | 364 | int pos = 0, ret, act_len, i, adap_num; |
365 | u8 b[16]; | ||
366 | u32 fw_version; | ||
332 | 367 | ||
333 | u8 buf[260]; | 368 | u8 buf[260]; |
334 | 369 | ||
@@ -364,6 +399,34 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw | |||
364 | } else | 399 | } else |
365 | ret = -EIO; | 400 | ret = -EIO; |
366 | 401 | ||
402 | /* the number of ts packet has to be at least 1 */ | ||
403 | if (nb_packet_buffer_size < 1) | ||
404 | nb_packet_buffer_size = 1; | ||
405 | |||
406 | /* get the fimware version */ | ||
407 | usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
408 | REQUEST_GET_VERSION, | ||
409 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, | ||
410 | b, sizeof(b), USB_CTRL_GET_TIMEOUT); | ||
411 | fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; | ||
412 | |||
413 | /* set the buffer size - DVB-USB is allocating URB buffers | ||
414 | * only after the firwmare download was successful */ | ||
415 | for (i = 0; i < dib0700_device_count; i++) { | ||
416 | for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters; | ||
417 | adap_num++) { | ||
418 | if (fw_version >= 0x10201) | ||
419 | dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size; | ||
420 | else { | ||
421 | /* for fw version older than 1.20.1, | ||
422 | * the buffersize has to be n times 512 */ | ||
423 | dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512; | ||
424 | if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512) | ||
425 | dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512; | ||
426 | } | ||
427 | } | ||
428 | } | ||
429 | |||
367 | return ret; | 430 | return ret; |
368 | } | 431 | } |
369 | 432 | ||
@@ -371,6 +434,18 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | |||
371 | { | 434 | { |
372 | struct dib0700_state *st = adap->dev->priv; | 435 | struct dib0700_state *st = adap->dev->priv; |
373 | u8 b[4]; | 436 | u8 b[4]; |
437 | int ret; | ||
438 | |||
439 | if ((onoff != 0) && (st->fw_version >= 0x10201)) { | ||
440 | /* for firmware later than 1.20.1, | ||
441 | * the USB xfer length can be set */ | ||
442 | ret = dib0700_set_usb_xfer_len(adap->dev, | ||
443 | st->nb_packet_buffer_size); | ||
444 | if (ret < 0) { | ||
445 | deb_info("can not set the USB xfer len\n"); | ||
446 | return ret; | ||
447 | } | ||
448 | } | ||
374 | 449 | ||
375 | b[0] = REQUEST_ENABLE_VIDEO; | 450 | b[0] = REQUEST_ENABLE_VIDEO; |
376 | b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ | 451 | b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ |
@@ -415,9 +490,21 @@ static int dib0700_probe(struct usb_interface *intf, | |||
415 | 490 | ||
416 | for (i = 0; i < dib0700_device_count; i++) | 491 | for (i = 0; i < dib0700_device_count; i++) |
417 | if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, | 492 | if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, |
418 | &dev, adapter_nr) == 0) | 493 | &dev, adapter_nr) == 0) { |
419 | { | 494 | struct dib0700_state *st = dev->priv; |
495 | u32 hwversion, romversion, fw_version, fwtype; | ||
496 | |||
497 | dib0700_get_version(dev, &hwversion, &romversion, | ||
498 | &fw_version, &fwtype); | ||
499 | |||
500 | deb_info("Firmware version: %x, %d, 0x%x, %d\n", | ||
501 | hwversion, romversion, fw_version, fwtype); | ||
502 | |||
503 | st->fw_version = fw_version; | ||
504 | st->nb_packet_buffer_size = (u32)nb_packet_buffer_size; | ||
505 | |||
420 | dib0700_rc_setup(dev); | 506 | dib0700_rc_setup(dev); |
507 | |||
421 | return 0; | 508 | return 0; |
422 | } | 509 | } |
423 | 510 | ||
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 684146f98eb..44972d01bbd 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "xc5000.h" | 18 | #include "xc5000.h" |
19 | #include "s5h1411.h" | 19 | #include "s5h1411.h" |
20 | #include "dib0070.h" | 20 | #include "dib0070.h" |
21 | #include "dib0090.h" | ||
21 | #include "lgdt3305.h" | 22 | #include "lgdt3305.h" |
22 | #include "mxl5007t.h" | 23 | #include "mxl5007t.h" |
23 | 24 | ||
@@ -130,93 +131,95 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap) | |||
130 | /* MT226x */ | 131 | /* MT226x */ |
131 | static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = { | 132 | static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = { |
132 | { | 133 | { |
133 | BAND_UHF, // band_caps | 134 | BAND_UHF, |
134 | 135 | ||
135 | /* 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, | 136 | /* 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, |
136 | * 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 */ | 137 | * 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 */ |
137 | (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup | 138 | (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) |
138 | 139 | | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | |
139 | 1130, // inv_gain | 140 | |
140 | 21, // time_stabiliz | 141 | 1130, |
141 | 142 | 21, | |
142 | 0, // alpha_level | 143 | |
143 | 118, // thlock | 144 | 0, |
144 | 145 | 118, | |
145 | 0, // wbd_inv | 146 | |
146 | 3530, // wbd_ref | 147 | 0, |
147 | 1, // wbd_sel | 148 | 3530, |
148 | 0, // wbd_alpha | 149 | 1, |
149 | 150 | 0, | |
150 | 65535, // agc1_max | 151 | |
151 | 33770, // agc1_min | 152 | 65535, |
152 | 65535, // agc2_max | 153 | 33770, |
153 | 23592, // agc2_min | 154 | 65535, |
154 | 155 | 23592, | |
155 | 0, // agc1_pt1 | 156 | |
156 | 62, // agc1_pt2 | 157 | 0, |
157 | 255, // agc1_pt3 | 158 | 62, |
158 | 64, // agc1_slope1 | 159 | 255, |
159 | 64, // agc1_slope2 | 160 | 64, |
160 | 132, // agc2_pt1 | 161 | 64, |
161 | 192, // agc2_pt2 | 162 | 132, |
162 | 80, // agc2_slope1 | 163 | 192, |
163 | 80, // agc2_slope2 | 164 | 80, |
164 | 165 | 80, | |
165 | 17, // alpha_mant | 166 | |
166 | 27, // alpha_exp | 167 | 17, |
167 | 23, // beta_mant | 168 | 27, |
168 | 51, // beta_exp | 169 | 23, |
169 | 170 | 51, | |
170 | 1, // perform_agc_softsplit | 171 | |
172 | 1, | ||
171 | }, { | 173 | }, { |
172 | BAND_VHF | BAND_LBAND, // band_caps | 174 | BAND_VHF | BAND_LBAND, |
173 | 175 | ||
174 | /* 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, | 176 | /* 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, |
175 | * 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 */ | 177 | * 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 */ |
176 | (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup | 178 | (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) |
177 | 179 | | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), | |
178 | 2372, // inv_gain | 180 | |
179 | 21, // time_stabiliz | 181 | 2372, |
180 | 182 | 21, | |
181 | 0, // alpha_level | 183 | |
182 | 118, // thlock | 184 | 0, |
183 | 185 | 118, | |
184 | 0, // wbd_inv | 186 | |
185 | 3530, // wbd_ref | 187 | 0, |
186 | 1, // wbd_sel | 188 | 3530, |
187 | 0, // wbd_alpha | 189 | 1, |
188 | 190 | 0, | |
189 | 65535, // agc1_max | 191 | |
190 | 0, // agc1_min | 192 | 65535, |
191 | 65535, // agc2_max | 193 | 0, |
192 | 23592, // agc2_min | 194 | 65535, |
193 | 195 | 23592, | |
194 | 0, // agc1_pt1 | 196 | |
195 | 128, // agc1_pt2 | 197 | 0, |
196 | 128, // agc1_pt3 | 198 | 128, |
197 | 128, // agc1_slope1 | 199 | 128, |
198 | 0, // agc1_slope2 | 200 | 128, |
199 | 128, // agc2_pt1 | 201 | 0, |
200 | 253, // agc2_pt2 | 202 | 128, |
201 | 81, // agc2_slope1 | 203 | 253, |
202 | 0, // agc2_slope2 | 204 | 81, |
203 | 205 | 0, | |
204 | 17, // alpha_mant | 206 | |
205 | 27, // alpha_exp | 207 | 17, |
206 | 23, // beta_mant | 208 | 27, |
207 | 51, // beta_exp | 209 | 23, |
208 | 210 | 51, | |
209 | 1, // perform_agc_softsplit | 211 | |
212 | 1, | ||
210 | } | 213 | } |
211 | }; | 214 | }; |
212 | 215 | ||
213 | static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = { | 216 | static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = { |
214 | 60000, 30000, // internal, sampling | 217 | 60000, 30000, |
215 | 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass | 218 | 1, 8, 3, 1, 0, |
216 | 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo | 219 | 0, 0, 1, 1, 2, |
217 | (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k | 220 | (3 << 14) | (1 << 12) | (524 << 0), |
218 | 0, // ifreq | 221 | 0, |
219 | 20452225, // timf | 222 | 20452225, |
220 | }; | 223 | }; |
221 | 224 | ||
222 | static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = { | 225 | static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = { |
@@ -605,17 +608,17 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, | |||
605 | } | 608 | } |
606 | break; | 609 | break; |
607 | default: | 610 | default: |
608 | if (actlen != sizeof(buf)) { | 611 | if (actlen != sizeof(buf)) { |
609 | /* We didn't get back the 6 byte message we expected */ | 612 | /* We didn't get back the 6 byte message we expected */ |
610 | err("Unexpected RC response size [%d]", actlen); | 613 | err("Unexpected RC response size [%d]", actlen); |
611 | return -1; | 614 | return -1; |
612 | } | 615 | } |
613 | 616 | ||
614 | poll_reply.report_id = buf[0]; | 617 | poll_reply.report_id = buf[0]; |
615 | poll_reply.data_state = buf[1]; | 618 | poll_reply.data_state = buf[1]; |
616 | poll_reply.system = (buf[2] << 8) | buf[3]; | 619 | poll_reply.system = (buf[2] << 8) | buf[3]; |
617 | poll_reply.data = buf[4]; | 620 | poll_reply.data = buf[4]; |
618 | poll_reply.not_data = buf[5]; | 621 | poll_reply.not_data = buf[5]; |
619 | 622 | ||
620 | break; | 623 | break; |
621 | } | 624 | } |
@@ -632,7 +635,7 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, | |||
632 | /* Find the key in the map */ | 635 | /* Find the key in the map */ |
633 | for (i = 0; i < d->props.rc_key_map_size; i++) { | 636 | for (i = 0; i < d->props.rc_key_map_size; i++) { |
634 | if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) && | 637 | if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) && |
635 | rc5_data(&keymap[i]) == poll_reply.data) { | 638 | rc5_data(&keymap[i]) == poll_reply.data) { |
636 | *event = keymap[i].event; | 639 | *event = keymap[i].event; |
637 | found = 1; | 640 | found = 1; |
638 | break; | 641 | break; |
@@ -641,8 +644,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, | |||
641 | 644 | ||
642 | if (found == 0) { | 645 | if (found == 0) { |
643 | err("Unknown remote controller key: %04x %02x %02x", | 646 | err("Unknown remote controller key: %04x %02x %02x", |
644 | poll_reply.system, | 647 | poll_reply.system, |
645 | poll_reply.data, poll_reply.not_data); | 648 | poll_reply.data, poll_reply.not_data); |
646 | d->last_event = 0; | 649 | d->last_event = 0; |
647 | return 0; | 650 | return 0; |
648 | } | 651 | } |
@@ -933,47 +936,48 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = { | |||
933 | 936 | ||
934 | /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ | 937 | /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ |
935 | static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = { | 938 | static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = { |
936 | BAND_UHF | BAND_VHF, // band_caps | 939 | BAND_UHF | BAND_VHF, |
937 | 940 | ||
938 | /* 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, | 941 | /* 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, |
939 | * 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 */ | 942 | * 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 */ |
940 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup | 943 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
941 | 944 | | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), | |
942 | 712, // inv_gain | 945 | |
943 | 41, // time_stabiliz | 946 | 712, |
944 | 947 | 41, | |
945 | 0, // alpha_level | 948 | |
946 | 118, // thlock | 949 | 0, |
947 | 950 | 118, | |
948 | 0, // wbd_inv | 951 | |
949 | 4095, // wbd_ref | 952 | 0, |
950 | 0, // wbd_sel | 953 | 4095, |
951 | 0, // wbd_alpha | 954 | 0, |
952 | 955 | 0, | |
953 | 42598, // agc1_max | 956 | |
954 | 17694, // agc1_min | 957 | 42598, |
955 | 45875, // agc2_max | 958 | 17694, |
956 | 2621, // agc2_min | 959 | 45875, |
957 | 0, // agc1_pt1 | 960 | 2621, |
958 | 76, // agc1_pt2 | 961 | 0, |
959 | 139, // agc1_pt3 | 962 | 76, |
960 | 52, // agc1_slope1 | 963 | 139, |
961 | 59, // agc1_slope2 | 964 | 52, |
962 | 107, // agc2_pt1 | 965 | 59, |
963 | 172, // agc2_pt2 | 966 | 107, |
964 | 57, // agc2_slope1 | 967 | 172, |
965 | 70, // agc2_slope2 | 968 | 57, |
966 | 969 | 70, | |
967 | 21, // alpha_mant | 970 | |
968 | 25, // alpha_exp | 971 | 21, |
969 | 28, // beta_mant | 972 | 25, |
970 | 48, // beta_exp | 973 | 28, |
971 | 974 | 48, | |
972 | 1, // perform_agc_softsplit | 975 | |
973 | { 0, // split_min | 976 | 1, |
974 | 107, // split_max | 977 | { 0, |
975 | 51800, // global_split_min | 978 | 107, |
976 | 24700 // global_split_max | 979 | 51800, |
980 | 24700 | ||
977 | }, | 981 | }, |
978 | }; | 982 | }; |
979 | 983 | ||
@@ -982,54 +986,55 @@ static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = { | |||
982 | 986 | ||
983 | /* 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, | 987 | /* 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, |
984 | * 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 */ | 988 | * 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 */ |
985 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup | 989 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
990 | | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), | ||
986 | 991 | ||
987 | 712, // inv_gain | 992 | 712, |
988 | 41, // time_stabiliz | 993 | 41, |
989 | 994 | ||
990 | 0, // alpha_level | 995 | 0, |
991 | 118, // thlock | 996 | 118, |
992 | 997 | ||
993 | 0, // wbd_inv | 998 | 0, |
994 | 4095, // wbd_ref | 999 | 4095, |
995 | 0, // wbd_sel | 1000 | 0, |
996 | 0, // wbd_alpha | 1001 | 0, |
997 | 1002 | ||
998 | 42598, // agc1_max | 1003 | 42598, |
999 | 16384, // agc1_min | 1004 | 16384, |
1000 | 42598, // agc2_max | 1005 | 42598, |
1001 | 0, // agc2_min | 1006 | 0, |
1002 | 1007 | ||
1003 | 0, // agc1_pt1 | 1008 | 0, |
1004 | 137, // agc1_pt2 | 1009 | 137, |
1005 | 255, // agc1_pt3 | 1010 | 255, |
1006 | 1011 | ||
1007 | 0, // agc1_slope1 | 1012 | 0, |
1008 | 255, // agc1_slope2 | 1013 | 255, |
1009 | 1014 | ||
1010 | 0, // agc2_pt1 | 1015 | 0, |
1011 | 0, // agc2_pt2 | 1016 | 0, |
1012 | 1017 | ||
1013 | 0, // agc2_slope1 | 1018 | 0, |
1014 | 41, // agc2_slope2 | 1019 | 41, |
1015 | 1020 | ||
1016 | 15, // alpha_mant | 1021 | 15, |
1017 | 25, // alpha_exp | 1022 | 25, |
1018 | 1023 | ||
1019 | 28, // beta_mant | 1024 | 28, |
1020 | 48, // beta_exp | 1025 | 48, |
1021 | 1026 | ||
1022 | 0, // perform_agc_softsplit | 1027 | 0, |
1023 | }; | 1028 | }; |
1024 | 1029 | ||
1025 | static struct dibx000_bandwidth_config stk7700p_pll_config = { | 1030 | static struct dibx000_bandwidth_config stk7700p_pll_config = { |
1026 | 60000, 30000, // internal, sampling | 1031 | 60000, 30000, |
1027 | 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass | 1032 | 1, 8, 3, 1, 0, |
1028 | 0, 0, 1, 1, 0, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo | 1033 | 0, 0, 1, 1, 0, |
1029 | (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k | 1034 | (3 << 14) | (1 << 12) | (524 << 0), |
1030 | 60258167, // ifreq | 1035 | 60258167, |
1031 | 20452225, // timf | 1036 | 20452225, |
1032 | 30000000, // xtal | 1037 | 30000000, |
1033 | }; | 1038 | }; |
1034 | 1039 | ||
1035 | static struct dib7000m_config stk7700p_dib7000m_config = { | 1040 | static struct dib7000m_config stk7700p_dib7000m_config = { |
@@ -1115,41 +1120,42 @@ static struct dibx000_agc_config dib7070_agc_config = { | |||
1115 | BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, | 1120 | BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, |
1116 | /* 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, | 1121 | /* 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, |
1117 | * 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 */ | 1122 | * 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 */ |
1118 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup | 1123 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
1119 | 1124 | | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | |
1120 | 600, // inv_gain | 1125 | |
1121 | 10, // time_stabiliz | 1126 | 600, |
1122 | 1127 | 10, | |
1123 | 0, // alpha_level | 1128 | |
1124 | 118, // thlock | 1129 | 0, |
1125 | 1130 | 118, | |
1126 | 0, // wbd_inv | 1131 | |
1127 | 3530, // wbd_ref | 1132 | 0, |
1128 | 1, // wbd_sel | 1133 | 3530, |
1129 | 5, // wbd_alpha | 1134 | 1, |
1130 | 1135 | 5, | |
1131 | 65535, // agc1_max | 1136 | |
1132 | 0, // agc1_min | 1137 | 65535, |
1133 | 1138 | 0, | |
1134 | 65535, // agc2_max | 1139 | |
1135 | 0, // agc2_min | 1140 | 65535, |
1136 | 1141 | 0, | |
1137 | 0, // agc1_pt1 | 1142 | |
1138 | 40, // agc1_pt2 | 1143 | 0, |
1139 | 183, // agc1_pt3 | 1144 | 40, |
1140 | 206, // agc1_slope1 | 1145 | 183, |
1141 | 255, // agc1_slope2 | 1146 | 206, |
1142 | 72, // agc2_pt1 | 1147 | 255, |
1143 | 152, // agc2_pt2 | 1148 | 72, |
1144 | 88, // agc2_slope1 | 1149 | 152, |
1145 | 90, // agc2_slope2 | 1150 | 88, |
1146 | 1151 | 90, | |
1147 | 17, // alpha_mant | 1152 | |
1148 | 27, // alpha_exp | 1153 | 17, |
1149 | 23, // beta_mant | 1154 | 27, |
1150 | 51, // beta_exp | 1155 | 23, |
1151 | 1156 | 51, | |
1152 | 0, // perform_agc_softsplit | 1157 | |
1158 | 0, | ||
1153 | }; | 1159 | }; |
1154 | 1160 | ||
1155 | static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) | 1161 | static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) |
@@ -1276,13 +1282,13 @@ static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) | |||
1276 | } | 1282 | } |
1277 | 1283 | ||
1278 | static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { | 1284 | static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { |
1279 | 60000, 15000, // internal, sampling | 1285 | 60000, 15000, |
1280 | 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass | 1286 | 1, 20, 3, 1, 0, |
1281 | 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo | 1287 | 0, 0, 1, 1, 2, |
1282 | (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k | 1288 | (3 << 14) | (1 << 12) | (524 << 0), |
1283 | (0 << 25) | 0, // ifreq = 0.000000 MHz | 1289 | (0 << 25) | 0, |
1284 | 20452225, // timf | 1290 | 20452225, |
1285 | 12000000, // xtal_hz | 1291 | 12000000, |
1286 | }; | 1292 | }; |
1287 | 1293 | ||
1288 | static struct dib7000p_config dib7070p_dib7000p_config = { | 1294 | static struct dib7000p_config dib7070p_dib7000p_config = { |
@@ -1476,12 +1482,12 @@ static struct dib8000_config dib807x_dib8000_config[2] = { | |||
1476 | } | 1482 | } |
1477 | }; | 1483 | }; |
1478 | 1484 | ||
1479 | static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff) | 1485 | static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff) |
1480 | { | 1486 | { |
1481 | return dib8000_set_gpio(fe, 5, 0, !onoff); | 1487 | return dib8000_set_gpio(fe, 5, 0, !onoff); |
1482 | } | 1488 | } |
1483 | 1489 | ||
1484 | static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff) | 1490 | static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff) |
1485 | { | 1491 | { |
1486 | return dib8000_set_gpio(fe, 0, 0, onoff); | 1492 | return dib8000_set_gpio(fe, 0, 0, onoff); |
1487 | } | 1493 | } |
@@ -1494,8 +1500,8 @@ static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = { | |||
1494 | static struct dib0070_config dib807x_dib0070_config[2] = { | 1500 | static struct dib0070_config dib807x_dib0070_config[2] = { |
1495 | { | 1501 | { |
1496 | .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, | 1502 | .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, |
1497 | .reset = dib807x_tuner_reset, | 1503 | .reset = dib80xx_tuner_reset, |
1498 | .sleep = dib807x_tuner_sleep, | 1504 | .sleep = dib80xx_tuner_sleep, |
1499 | .clock_khz = 12000, | 1505 | .clock_khz = 12000, |
1500 | .clock_pad_drive = 4, | 1506 | .clock_pad_drive = 4, |
1501 | .vga_filter = 1, | 1507 | .vga_filter = 1, |
@@ -1508,8 +1514,8 @@ static struct dib0070_config dib807x_dib0070_config[2] = { | |||
1508 | .freq_offset_khz_vhf = -100, | 1514 | .freq_offset_khz_vhf = -100, |
1509 | }, { | 1515 | }, { |
1510 | .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, | 1516 | .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, |
1511 | .reset = dib807x_tuner_reset, | 1517 | .reset = dib80xx_tuner_reset, |
1512 | .sleep = dib807x_tuner_sleep, | 1518 | .sleep = dib80xx_tuner_sleep, |
1513 | .clock_khz = 12000, | 1519 | .clock_khz = 12000, |
1514 | .clock_pad_drive = 2, | 1520 | .clock_pad_drive = 2, |
1515 | .vga_filter = 1, | 1521 | .vga_filter = 1, |
@@ -1566,12 +1572,14 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) | |||
1566 | return 0; | 1572 | return 0; |
1567 | } | 1573 | } |
1568 | 1574 | ||
1569 | static int stk807x_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) | 1575 | static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, |
1576 | u16 pid, int onoff) | ||
1570 | { | 1577 | { |
1571 | return dib8000_pid_filter(adapter->fe, index, pid, onoff); | 1578 | return dib8000_pid_filter(adapter->fe, index, pid, onoff); |
1572 | } | 1579 | } |
1573 | 1580 | ||
1574 | static int stk807x_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) | 1581 | static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, |
1582 | int onoff) | ||
1575 | { | 1583 | { |
1576 | return dib8000_pid_filter_ctrl(adapter->fe, onoff); | 1584 | return dib8000_pid_filter_ctrl(adapter->fe, onoff); |
1577 | } | 1585 | } |
@@ -1624,7 +1632,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) | |||
1624 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | 1632 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); |
1625 | 1633 | ||
1626 | /* initialize IC 0 */ | 1634 | /* initialize IC 0 */ |
1627 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80); | 1635 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80); |
1628 | 1636 | ||
1629 | adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, | 1637 | adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, |
1630 | &dib807x_dib8000_config[0]); | 1638 | &dib807x_dib8000_config[0]); |
@@ -1635,7 +1643,7 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) | |||
1635 | static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) | 1643 | static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) |
1636 | { | 1644 | { |
1637 | /* initialize IC 1 */ | 1645 | /* initialize IC 1 */ |
1638 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82); | 1646 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82); |
1639 | 1647 | ||
1640 | adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, | 1648 | adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, |
1641 | &dib807x_dib8000_config[1]); | 1649 | &dib807x_dib8000_config[1]); |
@@ -1643,6 +1651,245 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) | |||
1643 | return adap->fe == NULL ? -ENODEV : 0; | 1651 | return adap->fe == NULL ? -ENODEV : 0; |
1644 | } | 1652 | } |
1645 | 1653 | ||
1654 | /* STK8096GP */ | ||
1655 | struct dibx000_agc_config dib8090_agc_config[2] = { | ||
1656 | { | ||
1657 | BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, | ||
1658 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, | ||
1659 | * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, | ||
1660 | * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ | ||
1661 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | ||
1662 | | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | ||
1663 | |||
1664 | 787, | ||
1665 | 10, | ||
1666 | |||
1667 | 0, | ||
1668 | 118, | ||
1669 | |||
1670 | 0, | ||
1671 | 3530, | ||
1672 | 1, | ||
1673 | 5, | ||
1674 | |||
1675 | 65535, | ||
1676 | 0, | ||
1677 | |||
1678 | 65535, | ||
1679 | 0, | ||
1680 | |||
1681 | 0, | ||
1682 | 32, | ||
1683 | 114, | ||
1684 | 143, | ||
1685 | 144, | ||
1686 | 114, | ||
1687 | 227, | ||
1688 | 116, | ||
1689 | 117, | ||
1690 | |||
1691 | 28, | ||
1692 | 26, | ||
1693 | 31, | ||
1694 | 51, | ||
1695 | |||
1696 | 0, | ||
1697 | }, | ||
1698 | { | ||
1699 | BAND_CBAND, | ||
1700 | /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, | ||
1701 | * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, | ||
1702 | * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ | ||
1703 | (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | ||
1704 | | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), | ||
1705 | |||
1706 | 787, | ||
1707 | 10, | ||
1708 | |||
1709 | 0, | ||
1710 | 118, | ||
1711 | |||
1712 | 0, | ||
1713 | 3530, | ||
1714 | 1, | ||
1715 | 5, | ||
1716 | |||
1717 | 0, | ||
1718 | 0, | ||
1719 | |||
1720 | 65535, | ||
1721 | 0, | ||
1722 | |||
1723 | 0, | ||
1724 | 32, | ||
1725 | 114, | ||
1726 | 143, | ||
1727 | 144, | ||
1728 | 114, | ||
1729 | 227, | ||
1730 | 116, | ||
1731 | 117, | ||
1732 | |||
1733 | 28, | ||
1734 | 26, | ||
1735 | 31, | ||
1736 | 51, | ||
1737 | |||
1738 | 0, | ||
1739 | } | ||
1740 | }; | ||
1741 | |||
1742 | static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { | ||
1743 | 54000, 13500, | ||
1744 | 1, 18, 3, 1, 0, | ||
1745 | 0, 0, 1, 1, 2, | ||
1746 | (3 << 14) | (1 << 12) | (599 << 0), | ||
1747 | (0 << 25) | 0, | ||
1748 | 20199727, | ||
1749 | 12000000, | ||
1750 | }; | ||
1751 | |||
1752 | static int dib8090_get_adc_power(struct dvb_frontend *fe) | ||
1753 | { | ||
1754 | return dib8000_get_adc_power(fe, 1); | ||
1755 | } | ||
1756 | |||
1757 | static struct dib8000_config dib809x_dib8000_config = { | ||
1758 | .output_mpeg2_in_188_bytes = 1, | ||
1759 | |||
1760 | .agc_config_count = 2, | ||
1761 | .agc = dib8090_agc_config, | ||
1762 | .agc_control = dib0090_dcc_freq, | ||
1763 | .pll = &dib8090_pll_config_12mhz, | ||
1764 | .tuner_is_baseband = 1, | ||
1765 | |||
1766 | .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, | ||
1767 | .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, | ||
1768 | .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, | ||
1769 | |||
1770 | .hostbus_diversity = 1, | ||
1771 | .div_cfg = 0x31, | ||
1772 | .output_mode = OUTMODE_MPEG2_FIFO, | ||
1773 | .drives = 0x2d98, | ||
1774 | .diversity_delay = 144, | ||
1775 | .refclksel = 3, | ||
1776 | }; | ||
1777 | |||
1778 | static struct dib0090_config dib809x_dib0090_config = { | ||
1779 | .io.pll_bypass = 1, | ||
1780 | .io.pll_range = 1, | ||
1781 | .io.pll_prediv = 1, | ||
1782 | .io.pll_loopdiv = 20, | ||
1783 | .io.adc_clock_ratio = 8, | ||
1784 | .io.pll_int_loop_filt = 0, | ||
1785 | .io.clock_khz = 12000, | ||
1786 | .reset = dib80xx_tuner_reset, | ||
1787 | .sleep = dib80xx_tuner_sleep, | ||
1788 | .clkouttobamse = 1, | ||
1789 | .analog_output = 1, | ||
1790 | .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS, | ||
1791 | .wbd_vhf_offset = 100, | ||
1792 | .wbd_cband_offset = 450, | ||
1793 | .use_pwm_agc = 1, | ||
1794 | .clkoutdrive = 1, | ||
1795 | .get_adc_power = dib8090_get_adc_power, | ||
1796 | .freq_offset_khz_uhf = 0, | ||
1797 | .freq_offset_khz_vhf = -143, | ||
1798 | }; | ||
1799 | |||
1800 | static int dib8096_set_param_override(struct dvb_frontend *fe, | ||
1801 | struct dvb_frontend_parameters *fep) | ||
1802 | { | ||
1803 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
1804 | struct dib0700_adapter_state *state = adap->priv; | ||
1805 | u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); | ||
1806 | u16 offset; | ||
1807 | int ret = 0; | ||
1808 | enum frontend_tune_state tune_state = CT_SHUTDOWN; | ||
1809 | u16 ltgain, rf_gain_limit; | ||
1810 | |||
1811 | ret = state->set_param_save(fe, fep); | ||
1812 | if (ret < 0) | ||
1813 | return ret; | ||
1814 | |||
1815 | switch (band) { | ||
1816 | case BAND_VHF: | ||
1817 | offset = 100; | ||
1818 | break; | ||
1819 | case BAND_UHF: | ||
1820 | offset = 550; | ||
1821 | break; | ||
1822 | default: | ||
1823 | offset = 0; | ||
1824 | break; | ||
1825 | } | ||
1826 | offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; | ||
1827 | dib8000_set_wbd_ref(fe, offset); | ||
1828 | |||
1829 | |||
1830 | if (band == BAND_CBAND) { | ||
1831 | deb_info("tuning in CBAND - soft-AGC startup\n"); | ||
1832 | /* TODO specific wbd target for dib0090 - needed for startup ? */ | ||
1833 | dib0090_set_tune_state(fe, CT_AGC_START); | ||
1834 | do { | ||
1835 | ret = dib0090_gain_control(fe); | ||
1836 | msleep(ret); | ||
1837 | tune_state = dib0090_get_tune_state(fe); | ||
1838 | if (tune_state == CT_AGC_STEP_0) | ||
1839 | dib8000_set_gpio(fe, 6, 0, 1); | ||
1840 | else if (tune_state == CT_AGC_STEP_1) { | ||
1841 | dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, <gain); | ||
1842 | if (rf_gain_limit == 0) | ||
1843 | dib8000_set_gpio(fe, 6, 0, 0); | ||
1844 | } | ||
1845 | } while (tune_state < CT_AGC_STOP); | ||
1846 | dib0090_pwm_gain_reset(fe); | ||
1847 | dib8000_pwm_agc_reset(fe); | ||
1848 | dib8000_set_tune_state(fe, CT_DEMOD_START); | ||
1849 | } else { | ||
1850 | deb_info("not tuning in CBAND - standard AGC startup\n"); | ||
1851 | dib0090_pwm_gain_reset(fe); | ||
1852 | } | ||
1853 | |||
1854 | return 0; | ||
1855 | } | ||
1856 | |||
1857 | static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) | ||
1858 | { | ||
1859 | struct dib0700_adapter_state *st = adap->priv; | ||
1860 | struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); | ||
1861 | |||
1862 | if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) | ||
1863 | return -ENODEV; | ||
1864 | |||
1865 | st->set_param_save = adap->fe->ops.tuner_ops.set_params; | ||
1866 | adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; | ||
1867 | return 0; | ||
1868 | } | ||
1869 | |||
1870 | static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) | ||
1871 | { | ||
1872 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
1873 | msleep(10); | ||
1874 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
1875 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
1876 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
1877 | |||
1878 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
1879 | |||
1880 | dib0700_ctrl_clock(adap->dev, 72, 1); | ||
1881 | |||
1882 | msleep(10); | ||
1883 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
1884 | msleep(10); | ||
1885 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
1886 | |||
1887 | dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); | ||
1888 | |||
1889 | adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config); | ||
1890 | |||
1891 | return adap->fe == NULL ? -ENODEV : 0; | ||
1892 | } | ||
1646 | 1893 | ||
1647 | /* STK7070PD */ | 1894 | /* STK7070PD */ |
1648 | static struct dib7000p_config stk7070pd_dib7000p_config[2] = { | 1895 | static struct dib7000p_config stk7070pd_dib7000p_config[2] = { |
@@ -1929,14 +2176,17 @@ struct usb_device_id dib0700_usb_id_table[] = { | |||
1929 | { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) }, | 2176 | { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) }, |
1930 | /* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) }, | 2177 | /* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) }, |
1931 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) }, | 2178 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) }, |
1932 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, | 2179 | { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV73ESE) }, |
1933 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, | 2180 | { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV282E) }, |
1934 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) }, | 2181 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) }, |
1935 | /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) }, | 2182 | /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) }, |
1936 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, | 2183 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, |
1937 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, | 2184 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, |
1938 | { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, | 2185 | { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, |
1939 | { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, | 2186 | { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, |
2187 | /* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, | ||
2188 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, | ||
2189 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) }, | ||
1940 | { 0 } /* Terminating entry */ | 2190 | { 0 } /* Terminating entry */ |
1941 | }; | 2191 | }; |
1942 | MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); | 2192 | MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); |
@@ -2238,11 +2488,11 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
2238 | { NULL }, | 2488 | { NULL }, |
2239 | }, | 2489 | }, |
2240 | { "Pinnacle PCTV 73e SE", | 2490 | { "Pinnacle PCTV 73e SE", |
2241 | { &dib0700_usb_id_table[57], NULL }, | 2491 | { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL }, |
2242 | { NULL }, | 2492 | { NULL }, |
2243 | }, | 2493 | }, |
2244 | { "Pinnacle PCTV 282e", | 2494 | { "Pinnacle PCTV 282e", |
2245 | { &dib0700_usb_id_table[58], NULL }, | 2495 | { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL }, |
2246 | { NULL }, | 2496 | { NULL }, |
2247 | }, | 2497 | }, |
2248 | }, | 2498 | }, |
@@ -2471,8 +2721,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
2471 | { | 2721 | { |
2472 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | 2722 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, |
2473 | .pid_filter_count = 32, | 2723 | .pid_filter_count = 32, |
2474 | .pid_filter = stk807x_pid_filter, | 2724 | .pid_filter = stk80xx_pid_filter, |
2475 | .pid_filter_ctrl = stk807x_pid_filter_ctrl, | 2725 | .pid_filter_ctrl = stk80xx_pid_filter_ctrl, |
2476 | .frontend_attach = stk807x_frontend_attach, | 2726 | .frontend_attach = stk807x_frontend_attach, |
2477 | .tuner_attach = dib807x_tuner_attach, | 2727 | .tuner_attach = dib807x_tuner_attach, |
2478 | 2728 | ||
@@ -2510,8 +2760,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
2510 | { | 2760 | { |
2511 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | 2761 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, |
2512 | .pid_filter_count = 32, | 2762 | .pid_filter_count = 32, |
2513 | .pid_filter = stk807x_pid_filter, | 2763 | .pid_filter = stk80xx_pid_filter, |
2514 | .pid_filter_ctrl = stk807x_pid_filter_ctrl, | 2764 | .pid_filter_ctrl = stk80xx_pid_filter_ctrl, |
2515 | .frontend_attach = stk807xpvr_frontend_attach0, | 2765 | .frontend_attach = stk807xpvr_frontend_attach0, |
2516 | .tuner_attach = dib807x_tuner_attach, | 2766 | .tuner_attach = dib807x_tuner_attach, |
2517 | 2767 | ||
@@ -2523,8 +2773,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
2523 | { | 2773 | { |
2524 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | 2774 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, |
2525 | .pid_filter_count = 32, | 2775 | .pid_filter_count = 32, |
2526 | .pid_filter = stk807x_pid_filter, | 2776 | .pid_filter = stk80xx_pid_filter, |
2527 | .pid_filter_ctrl = stk807x_pid_filter_ctrl, | 2777 | .pid_filter_ctrl = stk80xx_pid_filter_ctrl, |
2528 | .frontend_attach = stk807xpvr_frontend_attach1, | 2778 | .frontend_attach = stk807xpvr_frontend_attach1, |
2529 | .tuner_attach = dib807x_tuner_attach, | 2779 | .tuner_attach = dib807x_tuner_attach, |
2530 | 2780 | ||
@@ -2547,6 +2797,37 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
2547 | .rc_key_map = dib0700_rc_keys, | 2797 | .rc_key_map = dib0700_rc_keys, |
2548 | .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), | 2798 | .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), |
2549 | .rc_query = dib0700_rc_query | 2799 | .rc_query = dib0700_rc_query |
2800 | }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, | ||
2801 | .num_adapters = 1, | ||
2802 | .adapter = { | ||
2803 | { | ||
2804 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
2805 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
2806 | .pid_filter_count = 32, | ||
2807 | .pid_filter = stk80xx_pid_filter, | ||
2808 | .pid_filter_ctrl = stk80xx_pid_filter_ctrl, | ||
2809 | .frontend_attach = stk809x_frontend_attach, | ||
2810 | .tuner_attach = dib809x_tuner_attach, | ||
2811 | |||
2812 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | ||
2813 | |||
2814 | .size_of_priv = | ||
2815 | sizeof(struct dib0700_adapter_state), | ||
2816 | }, | ||
2817 | }, | ||
2818 | |||
2819 | .num_device_descs = 1, | ||
2820 | .devices = { | ||
2821 | { "DiBcom STK8096GP reference design", | ||
2822 | { &dib0700_usb_id_table[67], NULL }, | ||
2823 | { NULL }, | ||
2824 | }, | ||
2825 | }, | ||
2826 | |||
2827 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
2828 | .rc_key_map = dib0700_rc_keys, | ||
2829 | .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), | ||
2830 | .rc_query = dib0700_rc_query | ||
2550 | }, | 2831 | }, |
2551 | }; | 2832 | }; |
2552 | 2833 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index da34979b533..9143b5631e8 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c | |||
@@ -142,8 +142,13 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num | |||
142 | } else if ((msg[i].flags & I2C_M_RD) == 0) { | 142 | } else if ((msg[i].flags & I2C_M_RD) == 0) { |
143 | if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) | 143 | if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) |
144 | break; | 144 | break; |
145 | } else | 145 | } else if (msg[i].addr != 0x50) { |
146 | break; | 146 | /* 0x50 is the address of the eeprom - we need to protect it |
147 | * from dibusb's bad i2c implementation: reads without | ||
148 | * writing the offset before are forbidden */ | ||
149 | if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0) | ||
150 | break; | ||
151 | } | ||
147 | } | 152 | } |
148 | 153 | ||
149 | mutex_unlock(&d->i2c_mutex); | 154 | mutex_unlock(&d->i2c_mutex); |
@@ -243,6 +248,12 @@ static struct dib3000mc_config mod3000p_dib3000p_config = { | |||
243 | 248 | ||
244 | int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap) | 249 | int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap) |
245 | { | 250 | { |
251 | if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON && | ||
252 | adap->dev->udev->descriptor.idProduct == | ||
253 | USB_PID_LITEON_DVB_T_WARM) { | ||
254 | msleep(1000); | ||
255 | } | ||
256 | |||
246 | if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL || | 257 | if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL || |
247 | (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) { | 258 | (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) { |
248 | if (adap->priv != NULL) { | 259 | if (adap->priv != NULL) { |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index f1602d4ace6..bc3581d58ce 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #define USB_VID_MSI_2 0x1462 | 47 | #define USB_VID_MSI_2 0x1462 |
48 | #define USB_VID_OPERA1 0x695c | 48 | #define USB_VID_OPERA1 0x695c |
49 | #define USB_VID_PINNACLE 0x2304 | 49 | #define USB_VID_PINNACLE 0x2304 |
50 | #define USB_VID_PCTV 0x2013 | ||
50 | #define USB_VID_PIXELVIEW 0x1554 | 51 | #define USB_VID_PIXELVIEW 0x1554 |
51 | #define USB_VID_TECHNOTREND 0x0b48 | 52 | #define USB_VID_TECHNOTREND 0x0b48 |
52 | #define USB_VID_TERRATEC 0x0ccd | 53 | #define USB_VID_TERRATEC 0x0ccd |
@@ -101,6 +102,7 @@ | |||
101 | #define USB_PID_DIBCOM_STK7070PD 0x1ebe | 102 | #define USB_PID_DIBCOM_STK7070PD 0x1ebe |
102 | #define USB_PID_DIBCOM_STK807XP 0x1f90 | 103 | #define USB_PID_DIBCOM_STK807XP 0x1f90 |
103 | #define USB_PID_DIBCOM_STK807XPVR 0x1f98 | 104 | #define USB_PID_DIBCOM_STK807XPVR 0x1f98 |
105 | #define USB_PID_DIBCOM_STK8096GP 0x1fa0 | ||
104 | #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 | 106 | #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 |
105 | #define USB_PID_DIBCOM_STK7770P 0x1e80 | 107 | #define USB_PID_DIBCOM_STK7770P 0x1e80 |
106 | #define USB_PID_DPOSH_M9206_COLD 0x9206 | 108 | #define USB_PID_DPOSH_M9206_COLD 0x9206 |
@@ -211,6 +213,7 @@ | |||
211 | #define USB_PID_PINNACLE_PCTV801E_SE 0x023b | 213 | #define USB_PID_PINNACLE_PCTV801E_SE 0x023b |
212 | #define USB_PID_PINNACLE_PCTV73A 0x0243 | 214 | #define USB_PID_PINNACLE_PCTV73A 0x0243 |
213 | #define USB_PID_PINNACLE_PCTV73ESE 0x0245 | 215 | #define USB_PID_PINNACLE_PCTV73ESE 0x0245 |
216 | #define USB_PID_PINNACLE_PCTV74E 0x0246 | ||
214 | #define USB_PID_PINNACLE_PCTV282E 0x0248 | 217 | #define USB_PID_PINNACLE_PCTV282E 0x0248 |
215 | #define USB_PID_PIXELVIEW_SBTVD 0x5010 | 218 | #define USB_PID_PIXELVIEW_SBTVD 0x5010 |
216 | #define USB_PID_PCTV_200E 0x020e | 219 | #define USB_PID_PCTV_200E 0x020e |
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 5bb9479d154..64132c0cf80 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -20,6 +20,11 @@ | |||
20 | #include "tda1002x.h" | 20 | #include "tda1002x.h" |
21 | #include "mt312.h" | 21 | #include "mt312.h" |
22 | #include "zl10039.h" | 22 | #include "zl10039.h" |
23 | #include "ds3000.h" | ||
24 | #include "stv0900.h" | ||
25 | #include "stv6110.h" | ||
26 | #include "stb6100.h" | ||
27 | #include "stb6100_proc.h" | ||
23 | 28 | ||
24 | #ifndef USB_PID_DW2102 | 29 | #ifndef USB_PID_DW2102 |
25 | #define USB_PID_DW2102 0x2102 | 30 | #define USB_PID_DW2102 0x2102 |
@@ -37,12 +42,20 @@ | |||
37 | #define USB_PID_CINERGY_S 0x0064 | 42 | #define USB_PID_CINERGY_S 0x0064 |
38 | #endif | 43 | #endif |
39 | 44 | ||
45 | #ifndef USB_PID_TEVII_S630 | ||
46 | #define USB_PID_TEVII_S630 0xd630 | ||
47 | #endif | ||
48 | |||
40 | #ifndef USB_PID_TEVII_S650 | 49 | #ifndef USB_PID_TEVII_S650 |
41 | #define USB_PID_TEVII_S650 0xd650 | 50 | #define USB_PID_TEVII_S650 0xd650 |
42 | #endif | 51 | #endif |
43 | 52 | ||
44 | #ifndef USB_PID_TEVII_S630 | 53 | #ifndef USB_PID_TEVII_S660 |
45 | #define USB_PID_TEVII_S630 0xd630 | 54 | #define USB_PID_TEVII_S660 0xd660 |
55 | #endif | ||
56 | |||
57 | #ifndef USB_PID_PROF_1100 | ||
58 | #define USB_PID_PROF_1100 0xb012 | ||
46 | #endif | 59 | #endif |
47 | 60 | ||
48 | #define DW210X_READ_MSG 0 | 61 | #define DW210X_READ_MSG 0 |
@@ -55,6 +68,10 @@ | |||
55 | #define DW2102_VOLTAGE_CTRL (0x1800) | 68 | #define DW2102_VOLTAGE_CTRL (0x1800) |
56 | #define DW2102_RC_QUERY (0x1a00) | 69 | #define DW2102_RC_QUERY (0x1a00) |
57 | 70 | ||
71 | #define err_str "did not find the firmware file. (%s) " \ | ||
72 | "Please see linux/Documentation/dvb/ for more details " \ | ||
73 | "on firmware-problems." | ||
74 | |||
58 | struct dvb_usb_rc_keys_table { | 75 | struct dvb_usb_rc_keys_table { |
59 | struct dvb_usb_rc_key *rc_keys; | 76 | struct dvb_usb_rc_key *rc_keys; |
60 | int rc_keys_size; | 77 | int rc_keys_size; |
@@ -71,6 +88,12 @@ static int ir_keymap; | |||
71 | module_param_named(keymap, ir_keymap, int, 0644); | 88 | module_param_named(keymap, ir_keymap, int, 0644); |
72 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); | 89 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); |
73 | 90 | ||
91 | /* demod probe */ | ||
92 | static int demod_probe = 1; | ||
93 | module_param_named(demod, demod_probe, int, 0644); | ||
94 | MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 " | ||
95 | "4=stv0903+stb6100(or-able))."); | ||
96 | |||
74 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 97 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
75 | 98 | ||
76 | static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, | 99 | static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, |
@@ -183,7 +206,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, | |||
183 | switch (num) { | 206 | switch (num) { |
184 | case 2: | 207 | case 2: |
185 | /* read si2109 register by number */ | 208 | /* read si2109 register by number */ |
186 | buf6[0] = 0xd0; | 209 | buf6[0] = msg[0].addr << 1; |
187 | buf6[1] = msg[0].len; | 210 | buf6[1] = msg[0].len; |
188 | buf6[2] = msg[0].buf[0]; | 211 | buf6[2] = msg[0].buf[0]; |
189 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | 212 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, |
@@ -198,7 +221,7 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, | |||
198 | switch (msg[0].addr) { | 221 | switch (msg[0].addr) { |
199 | case 0x68: | 222 | case 0x68: |
200 | /* write to si2109 register */ | 223 | /* write to si2109 register */ |
201 | buf6[0] = 0xd0; | 224 | buf6[0] = msg[0].addr << 1; |
202 | buf6[1] = msg[0].len; | 225 | buf6[1] = msg[0].len; |
203 | memcpy(buf6 + 2, msg[0].buf, msg[0].len); | 226 | memcpy(buf6 + 2, msg[0].buf, msg[0].len); |
204 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, | 227 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, |
@@ -239,7 +262,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms | |||
239 | /* read */ | 262 | /* read */ |
240 | /* first write first register number */ | 263 | /* first write first register number */ |
241 | u8 ibuf[msg[1].len + 2], obuf[3]; | 264 | u8 ibuf[msg[1].len + 2], obuf[3]; |
242 | obuf[0] = 0xd0; | 265 | obuf[0] = msg[0].addr << 1; |
243 | obuf[1] = msg[0].len; | 266 | obuf[1] = msg[0].len; |
244 | obuf[2] = msg[0].buf[0]; | 267 | obuf[2] = msg[0].buf[0]; |
245 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | 268 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, |
@@ -256,7 +279,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms | |||
256 | case 0x68: { | 279 | case 0x68: { |
257 | /* write to register */ | 280 | /* write to register */ |
258 | u8 obuf[msg[0].len + 2]; | 281 | u8 obuf[msg[0].len + 2]; |
259 | obuf[0] = 0xd0; | 282 | obuf[0] = msg[0].addr << 1; |
260 | obuf[1] = msg[0].len; | 283 | obuf[1] = msg[0].len; |
261 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | 284 | memcpy(obuf + 2, msg[0].buf, msg[0].len); |
262 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | 285 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, |
@@ -266,7 +289,7 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms | |||
266 | case 0x61: { | 289 | case 0x61: { |
267 | /* write to tuner */ | 290 | /* write to tuner */ |
268 | u8 obuf[msg[0].len + 2]; | 291 | u8 obuf[msg[0].len + 2]; |
269 | obuf[0] = 0xc2; | 292 | obuf[0] = msg[0].addr << 1; |
270 | obuf[1] = msg[0].len; | 293 | obuf[1] = msg[0].len; |
271 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | 294 | memcpy(obuf + 2, msg[0].buf, msg[0].len); |
272 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | 295 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, |
@@ -301,78 +324,78 @@ static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], i | |||
301 | { | 324 | { |
302 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 325 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
303 | int ret = 0; | 326 | int ret = 0; |
304 | int len, i; | 327 | int len, i, j; |
305 | 328 | ||
306 | if (!d) | 329 | if (!d) |
307 | return -ENODEV; | 330 | return -ENODEV; |
308 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 331 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
309 | return -EAGAIN; | 332 | return -EAGAIN; |
310 | 333 | ||
311 | switch (num) { | 334 | for (j = 0; j < num; j++) { |
312 | case 2: { | 335 | switch (msg[j].addr) { |
313 | /* read */ | ||
314 | /* first write first register number */ | ||
315 | u8 ibuf[msg[1].len + 2], obuf[3]; | ||
316 | obuf[0] = 0xaa; | ||
317 | obuf[1] = msg[0].len; | ||
318 | obuf[2] = msg[0].buf[0]; | ||
319 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
320 | obuf, msg[0].len + 2, DW210X_WRITE_MSG); | ||
321 | /* second read registers */ | ||
322 | ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0, | ||
323 | ibuf, msg[1].len + 2, DW210X_READ_MSG); | ||
324 | memcpy(msg[1].buf, ibuf + 2, msg[1].len); | ||
325 | |||
326 | break; | ||
327 | } | ||
328 | case 1: | ||
329 | switch (msg[0].addr) { | ||
330 | case 0x55: { | ||
331 | if (msg[0].buf[0] == 0xf7) { | ||
332 | /* firmware */ | ||
333 | /* Write in small blocks */ | ||
334 | u8 obuf[19]; | ||
335 | obuf[0] = 0xaa; | ||
336 | obuf[1] = 0x11; | ||
337 | obuf[2] = 0xf7; | ||
338 | len = msg[0].len - 1; | ||
339 | i = 1; | ||
340 | do { | ||
341 | memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len)); | ||
342 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
343 | obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG); | ||
344 | i += 16; | ||
345 | len -= 16; | ||
346 | } while (len > 0); | ||
347 | } else { | ||
348 | /* write to register */ | ||
349 | u8 obuf[msg[0].len + 2]; | ||
350 | obuf[0] = 0xaa; | ||
351 | obuf[1] = msg[0].len; | ||
352 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | ||
353 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
354 | obuf, msg[0].len + 2, DW210X_WRITE_MSG); | ||
355 | } | ||
356 | break; | ||
357 | } | ||
358 | case(DW2102_RC_QUERY): { | 336 | case(DW2102_RC_QUERY): { |
359 | u8 ibuf[2]; | 337 | u8 ibuf[2]; |
360 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, | 338 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, |
361 | ibuf, 2, DW210X_READ_MSG); | 339 | ibuf, 2, DW210X_READ_MSG); |
362 | memcpy(msg[0].buf, ibuf , 2); | 340 | memcpy(msg[j].buf, ibuf , 2); |
363 | break; | 341 | break; |
364 | } | 342 | } |
365 | case(DW2102_VOLTAGE_CTRL): { | 343 | case(DW2102_VOLTAGE_CTRL): { |
366 | u8 obuf[2]; | 344 | u8 obuf[2]; |
367 | obuf[0] = 0x30; | 345 | obuf[0] = 0x30; |
368 | obuf[1] = msg[0].buf[0]; | 346 | obuf[1] = msg[j].buf[0]; |
369 | ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, | 347 | ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, |
370 | obuf, 2, DW210X_WRITE_MSG); | 348 | obuf, 2, DW210X_WRITE_MSG); |
371 | break; | 349 | break; |
372 | } | 350 | } |
351 | /*case 0x55: cx24116 | ||
352 | case 0x6a: stv0903 | ||
353 | case 0x68: ds3000, stv0903 | ||
354 | case 0x60: ts2020, stv6110, stb6100 */ | ||
355 | default: { | ||
356 | if (msg[j].flags == I2C_M_RD) { | ||
357 | /* read registers */ | ||
358 | u8 ibuf[msg[j].len + 2]; | ||
359 | ret = dw210x_op_rw(d->udev, 0xc3, | ||
360 | (msg[j].addr << 1) + 1, 0, | ||
361 | ibuf, msg[j].len + 2, | ||
362 | DW210X_READ_MSG); | ||
363 | memcpy(msg[j].buf, ibuf + 2, msg[j].len); | ||
364 | mdelay(10); | ||
365 | } else if (((msg[j].buf[0] == 0xb0) && | ||
366 | (msg[j].addr == 0x68)) || | ||
367 | ((msg[j].buf[0] == 0xf7) && | ||
368 | (msg[j].addr == 0x55))) { | ||
369 | /* write firmware */ | ||
370 | u8 obuf[19]; | ||
371 | obuf[0] = msg[j].addr << 1; | ||
372 | obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len); | ||
373 | obuf[2] = msg[j].buf[0]; | ||
374 | len = msg[j].len - 1; | ||
375 | i = 1; | ||
376 | do { | ||
377 | memcpy(obuf + 3, msg[j].buf + i, | ||
378 | (len > 16 ? 16 : len)); | ||
379 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
380 | obuf, (len > 16 ? 16 : len) + 3, | ||
381 | DW210X_WRITE_MSG); | ||
382 | i += 16; | ||
383 | len -= 16; | ||
384 | } while (len > 0); | ||
385 | } else { | ||
386 | /* write registers */ | ||
387 | u8 obuf[msg[j].len + 2]; | ||
388 | obuf[0] = msg[j].addr << 1; | ||
389 | obuf[1] = msg[j].len; | ||
390 | memcpy(obuf + 2, msg[j].buf, msg[j].len); | ||
391 | ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, | ||
392 | obuf, msg[j].len + 2, | ||
393 | DW210X_WRITE_MSG); | ||
394 | } | ||
395 | break; | ||
396 | } | ||
373 | } | 397 | } |
374 | 398 | ||
375 | break; | ||
376 | } | 399 | } |
377 | 400 | ||
378 | mutex_unlock(&d->i2c_mutex); | 401 | mutex_unlock(&d->i2c_mutex); |
@@ -442,63 +465,85 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
442 | return num; | 465 | return num; |
443 | } | 466 | } |
444 | 467 | ||
445 | static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | 468 | static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], |
446 | int num) | 469 | int num) |
447 | { | 470 | { |
448 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 471 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
449 | int ret = 0; | 472 | int ret = 0; |
473 | int len, i, j; | ||
450 | 474 | ||
451 | if (!d) | 475 | if (!d) |
452 | return -ENODEV; | 476 | return -ENODEV; |
453 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 477 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
454 | return -EAGAIN; | 478 | return -EAGAIN; |
455 | 479 | ||
456 | switch (num) { | 480 | for (j = 0; j < num; j++) { |
457 | case 2: { /* read */ | 481 | switch (msg[j].addr) { |
458 | u8 ibuf[msg[1].len], obuf[3]; | ||
459 | obuf[0] = msg[1].len; | ||
460 | obuf[1] = (msg[0].addr << 1); | ||
461 | obuf[2] = msg[0].buf[0]; | ||
462 | |||
463 | ret = dw210x_op_rw(d->udev, 0x90, 0, 0, | ||
464 | obuf, 3, DW210X_WRITE_MSG); | ||
465 | msleep(5); | ||
466 | ret = dw210x_op_rw(d->udev, 0x91, 0, 0, | ||
467 | ibuf, msg[1].len, DW210X_READ_MSG); | ||
468 | memcpy(msg[1].buf, ibuf, msg[1].len); | ||
469 | break; | ||
470 | } | ||
471 | case 1: | ||
472 | switch (msg[0].addr) { | ||
473 | case 0x60: | ||
474 | case 0x0e: { | ||
475 | /* write to zl10313, zl10039 register, */ | ||
476 | u8 obuf[msg[0].len + 2]; | ||
477 | obuf[0] = msg[0].len + 1; | ||
478 | obuf[1] = (msg[0].addr << 1); | ||
479 | memcpy(obuf + 2, msg[0].buf, msg[0].len); | ||
480 | ret = dw210x_op_rw(d->udev, 0x80, 0, 0, | ||
481 | obuf, msg[0].len + 2, DW210X_WRITE_MSG); | ||
482 | break; | ||
483 | } | ||
484 | case (DW2102_RC_QUERY): { | 482 | case (DW2102_RC_QUERY): { |
485 | u8 ibuf[4]; | 483 | u8 ibuf[4]; |
486 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, | 484 | ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, |
487 | ibuf, 4, DW210X_READ_MSG); | 485 | ibuf, 4, DW210X_READ_MSG); |
488 | msg[0].buf[0] = ibuf[3]; | 486 | memcpy(msg[j].buf, ibuf + 1, 2); |
489 | break; | 487 | break; |
490 | } | 488 | } |
491 | case (DW2102_VOLTAGE_CTRL): { | 489 | case (DW2102_VOLTAGE_CTRL): { |
492 | u8 obuf[2]; | 490 | u8 obuf[2]; |
493 | obuf[0] = 0x03; | 491 | obuf[0] = 3; |
494 | obuf[1] = msg[0].buf[0]; | 492 | obuf[1] = msg[j].buf[0]; |
495 | ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, | 493 | ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, |
496 | obuf, 2, DW210X_WRITE_MSG); | 494 | obuf, 2, DW210X_WRITE_MSG); |
497 | break; | 495 | break; |
498 | } | 496 | } |
497 | /*case 0x55: cx24116 | ||
498 | case 0x6a: stv0903 | ||
499 | case 0x68: ds3000, stv0903 | ||
500 | case 0x60: ts2020, stv6110, stb6100 | ||
501 | case 0xa0: eeprom */ | ||
502 | default: { | ||
503 | if (msg[j].flags == I2C_M_RD) { | ||
504 | /* read registers */ | ||
505 | u8 ibuf[msg[j].len]; | ||
506 | ret = dw210x_op_rw(d->udev, 0x91, 0, 0, | ||
507 | ibuf, msg[j].len, | ||
508 | DW210X_READ_MSG); | ||
509 | memcpy(msg[j].buf, ibuf, msg[j].len); | ||
510 | break; | ||
511 | } else if ((msg[j].buf[0] == 0xb0) && | ||
512 | (msg[j].addr == 0x68)) { | ||
513 | /* write firmware */ | ||
514 | u8 obuf[19]; | ||
515 | obuf[0] = (msg[j].len > 16 ? | ||
516 | 18 : msg[j].len + 1); | ||
517 | obuf[1] = msg[j].addr << 1; | ||
518 | obuf[2] = msg[j].buf[0]; | ||
519 | len = msg[j].len - 1; | ||
520 | i = 1; | ||
521 | do { | ||
522 | memcpy(obuf + 3, msg[j].buf + i, | ||
523 | (len > 16 ? 16 : len)); | ||
524 | ret = dw210x_op_rw(d->udev, 0x80, 0, 0, | ||
525 | obuf, (len > 16 ? 16 : len) + 3, | ||
526 | DW210X_WRITE_MSG); | ||
527 | i += 16; | ||
528 | len -= 16; | ||
529 | } while (len > 0); | ||
530 | } else { | ||
531 | /* write registers */ | ||
532 | u8 obuf[msg[j].len + 2]; | ||
533 | obuf[0] = msg[j].len + 1; | ||
534 | obuf[1] = (msg[j].addr << 1); | ||
535 | memcpy(obuf + 2, msg[j].buf, msg[j].len); | ||
536 | ret = dw210x_op_rw(d->udev, | ||
537 | (num > 1 ? 0x90 : 0x80), 0, 0, | ||
538 | obuf, msg[j].len + 2, | ||
539 | DW210X_WRITE_MSG); | ||
540 | break; | ||
541 | } | ||
542 | break; | ||
543 | } | ||
499 | } | 544 | } |
500 | 545 | ||
501 | break; | 546 | msleep(3); |
502 | } | 547 | } |
503 | 548 | ||
504 | mutex_unlock(&d->i2c_mutex); | 549 | mutex_unlock(&d->i2c_mutex); |
@@ -535,8 +580,8 @@ static struct i2c_algorithm dw3101_i2c_algo = { | |||
535 | .functionality = dw210x_i2c_func, | 580 | .functionality = dw210x_i2c_func, |
536 | }; | 581 | }; |
537 | 582 | ||
538 | static struct i2c_algorithm s630_i2c_algo = { | 583 | static struct i2c_algorithm s6x0_i2c_algo = { |
539 | .master_xfer = s630_i2c_transfer, | 584 | .master_xfer = s6x0_i2c_transfer, |
540 | .functionality = dw210x_i2c_func, | 585 | .functionality = dw210x_i2c_func, |
541 | }; | 586 | }; |
542 | 587 | ||
@@ -564,25 +609,34 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | |||
564 | return 0; | 609 | return 0; |
565 | }; | 610 | }; |
566 | 611 | ||
567 | static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | 612 | static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) |
568 | { | 613 | { |
569 | int i, ret; | 614 | int i, ret; |
570 | u8 buf[3], eeprom[256], eepromline[16]; | 615 | u8 ibuf[] = { 0 }, obuf[] = { 0 }; |
616 | u8 eeprom[256], eepromline[16]; | ||
617 | struct i2c_msg msg[] = { | ||
618 | { | ||
619 | .addr = 0xa0 >> 1, | ||
620 | .flags = 0, | ||
621 | .buf = obuf, | ||
622 | .len = 1, | ||
623 | }, { | ||
624 | .addr = 0xa0 >> 1, | ||
625 | .flags = I2C_M_RD, | ||
626 | .buf = ibuf, | ||
627 | .len = 1, | ||
628 | } | ||
629 | }; | ||
571 | 630 | ||
572 | for (i = 0; i < 256; i++) { | 631 | for (i = 0; i < 256; i++) { |
573 | buf[0] = 1; | 632 | obuf[0] = i; |
574 | buf[1] = 0xa0; | 633 | ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2); |
575 | buf[2] = i; | 634 | if (ret != 2) { |
576 | ret = dw210x_op_rw(d->udev, 0x90, 0, 0, | ||
577 | buf, 3, DW210X_WRITE_MSG); | ||
578 | ret = dw210x_op_rw(d->udev, 0x91, 0, 0, | ||
579 | buf, 1, DW210X_READ_MSG); | ||
580 | if (ret < 0) { | ||
581 | err("read eeprom failed."); | 635 | err("read eeprom failed."); |
582 | return -1; | 636 | return -1; |
583 | } else { | 637 | } else { |
584 | eepromline[i % 16] = buf[0]; | 638 | eepromline[i % 16] = ibuf[0]; |
585 | eeprom[i] = buf[0]; | 639 | eeprom[i] = ibuf[0]; |
586 | } | 640 | } |
587 | 641 | ||
588 | if ((i % 16) == 15) { | 642 | if ((i % 16) == 15) { |
@@ -644,19 +698,104 @@ static struct mt312_config zl313_config = { | |||
644 | .demod_address = 0x0e, | 698 | .demod_address = 0x0e, |
645 | }; | 699 | }; |
646 | 700 | ||
701 | static struct ds3000_config dw2104_ds3000_config = { | ||
702 | .demod_address = 0x68, | ||
703 | }; | ||
704 | |||
705 | static struct stv0900_config dw2104a_stv0900_config = { | ||
706 | .demod_address = 0x6a, | ||
707 | .demod_mode = 0, | ||
708 | .xtal = 27000000, | ||
709 | .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ | ||
710 | .diseqc_mode = 2,/* 2/3 PWM */ | ||
711 | .tun1_maddress = 0,/* 0x60 */ | ||
712 | .tun1_adc = 0,/* 2 Vpp */ | ||
713 | .path1_mode = 3, | ||
714 | }; | ||
715 | |||
716 | static struct stb6100_config dw2104a_stb6100_config = { | ||
717 | .tuner_address = 0x60, | ||
718 | .refclock = 27000000, | ||
719 | }; | ||
720 | |||
721 | static struct stv0900_config dw2104_stv0900_config = { | ||
722 | .demod_address = 0x68, | ||
723 | .demod_mode = 0, | ||
724 | .xtal = 8000000, | ||
725 | .clkmode = 3, | ||
726 | .diseqc_mode = 2, | ||
727 | .tun1_maddress = 0, | ||
728 | .tun1_adc = 1,/* 1 Vpp */ | ||
729 | .path1_mode = 3, | ||
730 | }; | ||
731 | |||
732 | static struct stv6110_config dw2104_stv6110_config = { | ||
733 | .i2c_address = 0x60, | ||
734 | .mclk = 16000000, | ||
735 | .clk_div = 1, | ||
736 | }; | ||
737 | |||
647 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | 738 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) |
648 | { | 739 | { |
649 | if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, | 740 | struct dvb_tuner_ops *tuner_ops = NULL; |
650 | &d->dev->i2c_adap)) != NULL) { | 741 | |
742 | if (demod_probe & 4) { | ||
743 | d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config, | ||
744 | &d->dev->i2c_adap, 0); | ||
745 | if (d->fe != NULL) { | ||
746 | if (dvb_attach(stb6100_attach, d->fe, | ||
747 | &dw2104a_stb6100_config, | ||
748 | &d->dev->i2c_adap)) { | ||
749 | tuner_ops = &d->fe->ops.tuner_ops; | ||
750 | tuner_ops->set_frequency = stb6100_set_freq; | ||
751 | tuner_ops->get_frequency = stb6100_get_freq; | ||
752 | tuner_ops->set_bandwidth = stb6100_set_bandw; | ||
753 | tuner_ops->get_bandwidth = stb6100_get_bandw; | ||
754 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
755 | info("Attached STV0900+STB6100!\n"); | ||
756 | return 0; | ||
757 | } | ||
758 | } | ||
759 | } | ||
760 | |||
761 | if (demod_probe & 2) { | ||
762 | d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config, | ||
763 | &d->dev->i2c_adap, 0); | ||
764 | if (d->fe != NULL) { | ||
765 | if (dvb_attach(stv6110_attach, d->fe, | ||
766 | &dw2104_stv6110_config, | ||
767 | &d->dev->i2c_adap)) { | ||
768 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
769 | info("Attached STV0900+STV6110A!\n"); | ||
770 | return 0; | ||
771 | } | ||
772 | } | ||
773 | } | ||
774 | |||
775 | if (demod_probe & 1) { | ||
776 | d->fe = dvb_attach(cx24116_attach, &dw2104_config, | ||
777 | &d->dev->i2c_adap); | ||
778 | if (d->fe != NULL) { | ||
779 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
780 | info("Attached cx24116!\n"); | ||
781 | return 0; | ||
782 | } | ||
783 | } | ||
784 | |||
785 | d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, | ||
786 | &d->dev->i2c_adap); | ||
787 | if (d->fe != NULL) { | ||
651 | d->fe->ops.set_voltage = dw210x_set_voltage; | 788 | d->fe->ops.set_voltage = dw210x_set_voltage; |
652 | info("Attached cx24116!\n"); | 789 | info("Attached DS3000!\n"); |
653 | return 0; | 790 | return 0; |
654 | } | 791 | } |
792 | |||
655 | return -EIO; | 793 | return -EIO; |
656 | } | 794 | } |
657 | 795 | ||
658 | static struct dvb_usb_device_properties dw2102_properties; | 796 | static struct dvb_usb_device_properties dw2102_properties; |
659 | static struct dvb_usb_device_properties dw2104_properties; | 797 | static struct dvb_usb_device_properties dw2104_properties; |
798 | static struct dvb_usb_device_properties s6x0_properties; | ||
660 | 799 | ||
661 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) | 800 | static int dw2102_frontend_attach(struct dvb_usb_adapter *d) |
662 | { | 801 | { |
@@ -670,14 +809,17 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) | |||
670 | return 0; | 809 | return 0; |
671 | } | 810 | } |
672 | } | 811 | } |
812 | |||
673 | if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { | 813 | if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { |
674 | /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ | ||
675 | d->fe = dvb_attach(stv0288_attach, &earda_config, | 814 | d->fe = dvb_attach(stv0288_attach, &earda_config, |
676 | &d->dev->i2c_adap); | 815 | &d->dev->i2c_adap); |
677 | if (d->fe != NULL) { | 816 | if (d->fe != NULL) { |
678 | d->fe->ops.set_voltage = dw210x_set_voltage; | 817 | if (dvb_attach(stb6000_attach, d->fe, 0x61, |
679 | info("Attached stv0288!\n"); | 818 | &d->dev->i2c_adap)) { |
680 | return 0; | 819 | d->fe->ops.set_voltage = dw210x_set_voltage; |
820 | info("Attached stv0288!\n"); | ||
821 | return 0; | ||
822 | } | ||
681 | } | 823 | } |
682 | } | 824 | } |
683 | 825 | ||
@@ -705,15 +847,38 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d) | |||
705 | return -EIO; | 847 | return -EIO; |
706 | } | 848 | } |
707 | 849 | ||
708 | static int s630_frontend_attach(struct dvb_usb_adapter *d) | 850 | static int s6x0_frontend_attach(struct dvb_usb_adapter *d) |
709 | { | 851 | { |
710 | d->fe = dvb_attach(mt312_attach, &zl313_config, | 852 | d->fe = dvb_attach(mt312_attach, &zl313_config, |
711 | &d->dev->i2c_adap); | 853 | &d->dev->i2c_adap); |
854 | if (d->fe != NULL) { | ||
855 | if (dvb_attach(zl10039_attach, d->fe, 0x60, | ||
856 | &d->dev->i2c_adap)) { | ||
857 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
858 | info("Attached zl100313+zl10039!\n"); | ||
859 | return 0; | ||
860 | } | ||
861 | } | ||
862 | |||
863 | d->fe = dvb_attach(stv0288_attach, &earda_config, | ||
864 | &d->dev->i2c_adap); | ||
865 | if (d->fe != NULL) { | ||
866 | if (dvb_attach(stb6000_attach, d->fe, 0x61, | ||
867 | &d->dev->i2c_adap)) { | ||
868 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
869 | info("Attached stv0288+stb6000!\n"); | ||
870 | return 0; | ||
871 | } | ||
872 | } | ||
873 | |||
874 | d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, | ||
875 | &d->dev->i2c_adap); | ||
712 | if (d->fe != NULL) { | 876 | if (d->fe != NULL) { |
713 | d->fe->ops.set_voltage = dw210x_set_voltage; | 877 | d->fe->ops.set_voltage = dw210x_set_voltage; |
714 | info("Attached zl10313!\n"); | 878 | info("Attached ds3000+ds2020!\n"); |
715 | return 0; | 879 | return 0; |
716 | } | 880 | } |
881 | |||
717 | return -EIO; | 882 | return -EIO; |
718 | } | 883 | } |
719 | 884 | ||
@@ -724,14 +889,6 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | |||
724 | return 0; | 889 | return 0; |
725 | } | 890 | } |
726 | 891 | ||
727 | static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap) | ||
728 | { | ||
729 | dvb_attach(stb6000_attach, adap->fe, 0x61, | ||
730 | &adap->dev->i2c_adap); | ||
731 | |||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) | 892 | static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) |
736 | { | 893 | { |
737 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, | 894 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, |
@@ -740,14 +897,6 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) | |||
740 | return 0; | 897 | return 0; |
741 | } | 898 | } |
742 | 899 | ||
743 | static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap) | ||
744 | { | ||
745 | dvb_attach(zl10039_attach, adap->fe, 0x60, | ||
746 | &adap->dev->i2c_adap); | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static struct dvb_usb_rc_key dw210x_rc_keys[] = { | 900 | static struct dvb_usb_rc_key dw210x_rc_keys[] = { |
752 | { 0xf80a, KEY_Q }, /*power*/ | 901 | { 0xf80a, KEY_Q }, /*power*/ |
753 | { 0xf80c, KEY_M }, /*mute*/ | 902 | { 0xf80c, KEY_M }, /*mute*/ |
@@ -922,6 +1071,8 @@ static struct usb_device_id dw2102_table[] = { | |||
922 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, | 1071 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, |
923 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, | 1072 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, |
924 | {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, | 1073 | {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, |
1074 | {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, | ||
1075 | {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, | ||
925 | { } | 1076 | { } |
926 | }; | 1077 | }; |
927 | 1078 | ||
@@ -935,15 +1086,13 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
935 | u8 reset; | 1086 | u8 reset; |
936 | u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; | 1087 | u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; |
937 | const struct firmware *fw; | 1088 | const struct firmware *fw; |
938 | const char *filename = "dvb-usb-dw2101.fw"; | 1089 | const char *fw_2101 = "dvb-usb-dw2101.fw"; |
939 | 1090 | ||
940 | switch (dev->descriptor.idProduct) { | 1091 | switch (dev->descriptor.idProduct) { |
941 | case 0x2101: | 1092 | case 0x2101: |
942 | ret = request_firmware(&fw, filename, &dev->dev); | 1093 | ret = request_firmware(&fw, fw_2101, &dev->dev); |
943 | if (ret != 0) { | 1094 | if (ret != 0) { |
944 | err("did not find the firmware file. (%s) " | 1095 | err(err_str, fw_2101); |
945 | "Please see linux/Documentation/dvb/ for more details " | ||
946 | "on firmware-problems.", filename); | ||
947 | return ret; | 1096 | return ret; |
948 | } | 1097 | } |
949 | break; | 1098 | break; |
@@ -983,6 +1132,11 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
983 | } | 1132 | } |
984 | /* init registers */ | 1133 | /* init registers */ |
985 | switch (dev->descriptor.idProduct) { | 1134 | switch (dev->descriptor.idProduct) { |
1135 | case USB_PID_PROF_1100: | ||
1136 | s6x0_properties.rc_key_map = tbs_rc_keys; | ||
1137 | s6x0_properties.rc_key_map_size = | ||
1138 | ARRAY_SIZE(tbs_rc_keys); | ||
1139 | break; | ||
986 | case USB_PID_TEVII_S650: | 1140 | case USB_PID_TEVII_S650: |
987 | dw2104_properties.rc_key_map = tevii_rc_keys; | 1141 | dw2104_properties.rc_key_map = tevii_rc_keys; |
988 | dw2104_properties.rc_key_map_size = | 1142 | dw2104_properties.rc_key_map_size = |
@@ -1021,7 +1175,6 @@ static int dw2102_load_firmware(struct usb_device *dev, | |||
1021 | DW210X_READ_MSG); | 1175 | DW210X_READ_MSG); |
1022 | if (reset16[2] == 0x11) { | 1176 | if (reset16[2] == 0x11) { |
1023 | dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; | 1177 | dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; |
1024 | dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach; | ||
1025 | break; | 1178 | break; |
1026 | } | 1179 | } |
1027 | } | 1180 | } |
@@ -1184,13 +1337,13 @@ static struct dvb_usb_device_properties dw3101_properties = { | |||
1184 | } | 1337 | } |
1185 | }; | 1338 | }; |
1186 | 1339 | ||
1187 | static struct dvb_usb_device_properties s630_properties = { | 1340 | static struct dvb_usb_device_properties s6x0_properties = { |
1188 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1341 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1189 | .usb_ctrl = DEVICE_SPECIFIC, | 1342 | .usb_ctrl = DEVICE_SPECIFIC, |
1190 | .firmware = "dvb-usb-s630.fw", | 1343 | .firmware = "dvb-usb-s630.fw", |
1191 | .no_reconnect = 1, | 1344 | .no_reconnect = 1, |
1192 | 1345 | ||
1193 | .i2c_algo = &s630_i2c_algo, | 1346 | .i2c_algo = &s6x0_i2c_algo, |
1194 | .rc_key_map = tevii_rc_keys, | 1347 | .rc_key_map = tevii_rc_keys, |
1195 | .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys), | 1348 | .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys), |
1196 | .rc_interval = 150, | 1349 | .rc_interval = 150, |
@@ -1199,12 +1352,12 @@ static struct dvb_usb_device_properties s630_properties = { | |||
1199 | .generic_bulk_ctrl_endpoint = 0x81, | 1352 | .generic_bulk_ctrl_endpoint = 0x81, |
1200 | .num_adapters = 1, | 1353 | .num_adapters = 1, |
1201 | .download_firmware = dw2102_load_firmware, | 1354 | .download_firmware = dw2102_load_firmware, |
1202 | .read_mac_address = s630_read_mac_address, | 1355 | .read_mac_address = s6x0_read_mac_address, |
1203 | .adapter = { | 1356 | .adapter = { |
1204 | { | 1357 | { |
1205 | .frontend_attach = s630_frontend_attach, | 1358 | .frontend_attach = s6x0_frontend_attach, |
1206 | .streaming_ctrl = NULL, | 1359 | .streaming_ctrl = NULL, |
1207 | .tuner_attach = s630_zl10039_tuner_attach, | 1360 | .tuner_attach = NULL, |
1208 | .stream = { | 1361 | .stream = { |
1209 | .type = USB_BULK, | 1362 | .type = USB_BULK, |
1210 | .count = 8, | 1363 | .count = 8, |
@@ -1217,12 +1370,20 @@ static struct dvb_usb_device_properties s630_properties = { | |||
1217 | }, | 1370 | }, |
1218 | } | 1371 | } |
1219 | }, | 1372 | }, |
1220 | .num_device_descs = 1, | 1373 | .num_device_descs = 3, |
1221 | .devices = { | 1374 | .devices = { |
1222 | {"TeVii S630 USB", | 1375 | {"TeVii S630 USB", |
1223 | {&dw2102_table[6], NULL}, | 1376 | {&dw2102_table[6], NULL}, |
1224 | {NULL}, | 1377 | {NULL}, |
1225 | }, | 1378 | }, |
1379 | {"Prof 1100 USB ", | ||
1380 | {&dw2102_table[7], NULL}, | ||
1381 | {NULL}, | ||
1382 | }, | ||
1383 | {"TeVii S660 USB", | ||
1384 | {&dw2102_table[8], NULL}, | ||
1385 | {NULL}, | ||
1386 | }, | ||
1226 | } | 1387 | } |
1227 | }; | 1388 | }; |
1228 | 1389 | ||
@@ -1235,10 +1396,10 @@ static int dw2102_probe(struct usb_interface *intf, | |||
1235 | THIS_MODULE, NULL, adapter_nr) || | 1396 | THIS_MODULE, NULL, adapter_nr) || |
1236 | 0 == dvb_usb_device_init(intf, &dw3101_properties, | 1397 | 0 == dvb_usb_device_init(intf, &dw3101_properties, |
1237 | THIS_MODULE, NULL, adapter_nr) || | 1398 | THIS_MODULE, NULL, adapter_nr) || |
1238 | 0 == dvb_usb_device_init(intf, &s630_properties, | 1399 | 0 == dvb_usb_device_init(intf, &s6x0_properties, |
1239 | THIS_MODULE, NULL, adapter_nr)) { | 1400 | THIS_MODULE, NULL, adapter_nr)) |
1240 | return 0; | 1401 | return 0; |
1241 | } | 1402 | |
1242 | return -ENODEV; | 1403 | return -ENODEV; |
1243 | } | 1404 | } |
1244 | 1405 | ||
@@ -1269,6 +1430,7 @@ module_exit(dw2102_module_exit); | |||
1269 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | 1430 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); |
1270 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," | 1431 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," |
1271 | " DVB-C 3101 USB2.0," | 1432 | " DVB-C 3101 USB2.0," |
1272 | " TeVii S600, S630, S650 USB2.0 devices"); | 1433 | " TeVii S600, S630, S650, S660 USB2.0," |
1434 | " Prof 1100 USB2.0 devices"); | ||
1273 | MODULE_VERSION("0.1"); | 1435 | MODULE_VERSION("0.1"); |
1274 | MODULE_LICENSE("GPL"); | 1436 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c index 9cbbe42ca44..ebb7b9fd115 100644 --- a/drivers/media/dvb/dvb-usb/friio-fe.c +++ b/drivers/media/dvb/dvb-usb/friio-fe.c | |||
@@ -134,11 +134,13 @@ static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq) | |||
134 | deb_fe("%s: freq=%d, step=%d\n", __func__, freq, | 134 | deb_fe("%s: freq=%d, step=%d\n", __func__, freq, |
135 | state->frontend.ops.info.frequency_stepsize); | 135 | state->frontend.ops.info.frequency_stepsize); |
136 | /* freq -> oscilator frequency conversion. */ | 136 | /* freq -> oscilator frequency conversion. */ |
137 | /* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */ | 137 | /* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */ |
138 | /* add 400[1/7 MHZ] = 57.142857MHz. 57MHz for the IF, */ | ||
139 | /* 1/7MHz for center freq shift */ | ||
140 | f = freq / state->frontend.ops.info.frequency_stepsize; | 138 | f = freq / state->frontend.ops.info.frequency_stepsize; |
141 | f += 400; | 139 | /* add 399[1/7 MHZ] = 57MHz for the IF */ |
140 | f += 399; | ||
141 | /* add center frequency shift if necessary */ | ||
142 | if (f % 7 == 0) | ||
143 | f++; | ||
142 | pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */ | 144 | pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */ |
143 | pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1; | 145 | pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1; |
144 | pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F; | 146 | pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F; |
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c index 20eadf9318e..7a7f1b2b681 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c | |||
@@ -146,8 +146,8 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, | |||
146 | 146 | ||
147 | switch (c->delivery_system) { | 147 | switch (c->delivery_system) { |
148 | case SYS_DVBS: | 148 | case SYS_DVBS: |
149 | /* Only QPSK is supported for DVB-S */ | 149 | /* Allow QPSK and 8PSK (even for DVB-S) */ |
150 | if (c->modulation != QPSK) { | 150 | if (c->modulation != QPSK && c->modulation != PSK_8) { |
151 | deb_fe("%s: unsupported modulation selected (%d)\n", | 151 | deb_fe("%s: unsupported modulation selected (%d)\n", |
152 | __func__, c->modulation); | 152 | __func__, c->modulation); |
153 | return -EOPNOTSUPP; | 153 | return -EOPNOTSUPP; |
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 58aac018f10..a3b8b697349 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -526,6 +526,15 @@ config DVB_TUNER_DIB0070 | |||
526 | This device is only used inside a SiP called together with a | 526 | This device is only used inside a SiP called together with a |
527 | demodulator for now. | 527 | demodulator for now. |
528 | 528 | ||
529 | config DVB_TUNER_DIB0090 | ||
530 | tristate "DiBcom DiB0090 silicon base-band tuner" | ||
531 | depends on I2C | ||
532 | default m if DVB_FE_CUSTOMISE | ||
533 | help | ||
534 | A driver for the silicon baseband tuner DiB0090 from DiBcom. | ||
535 | This device is only used inside a SiP called together with a | ||
536 | demodulator for now. | ||
537 | |||
529 | comment "SEC control devices for DVB-S" | 538 | comment "SEC control devices for DVB-S" |
530 | depends on DVB_CORE | 539 | depends on DVB_CORE |
531 | 540 | ||
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 823482535d1..47575cc7b69 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -55,6 +55,7 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o | |||
55 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o | 55 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o |
56 | obj-$(CONFIG_DVB_TDA8261) += tda8261.o | 56 | obj-$(CONFIG_DVB_TDA8261) += tda8261.o |
57 | obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o | 57 | obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o |
58 | obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o | ||
58 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o | 59 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o |
59 | obj-$(CONFIG_DVB_S5H1409) += s5h1409.o | 60 | obj-$(CONFIG_DVB_S5H1409) += s5h1409.o |
60 | obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o | 61 | obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o |
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index 2dc2723b724..24268ef2753 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c | |||
@@ -62,7 +62,7 @@ struct au8522_register_config { | |||
62 | The values are as follows from left to right | 62 | The values are as follows from left to right |
63 | 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13" | 63 | 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13" |
64 | */ | 64 | */ |
65 | struct au8522_register_config filter_coef[] = { | 65 | static const struct au8522_register_config filter_coef[] = { |
66 | {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} }, | 66 | {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} }, |
67 | {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} }, | 67 | {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} }, |
68 | {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} }, | 68 | {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} }, |
@@ -104,7 +104,7 @@ struct au8522_register_config filter_coef[] = { | |||
104 | 0="SIF" 1="ATVRF/ATVRF13" | 104 | 0="SIF" 1="ATVRF/ATVRF13" |
105 | Note: the "ATVRF/ATVRF13" mode has never been tested | 105 | Note: the "ATVRF/ATVRF13" mode has never been tested |
106 | */ | 106 | */ |
107 | struct au8522_register_config lpfilter_coef[] = { | 107 | static const struct au8522_register_config lpfilter_coef[] = { |
108 | {0x060b, {0x21, 0x0b} }, | 108 | {0x060b, {0x21, 0x0b} }, |
109 | {0x060c, {0xad, 0xad} }, | 109 | {0x060c, {0xad, 0xad} }, |
110 | {0x060d, {0x70, 0xf0} }, | 110 | {0x060d, {0x70, 0xf0} }, |
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c index 2be17b93e0b..0d12763603b 100644 --- a/drivers/media/dvb/frontends/dib0070.c +++ b/drivers/media/dvb/frontends/dib0070.c | |||
@@ -49,21 +49,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); | |||
49 | #define DIB0070_P1G 0x03 | 49 | #define DIB0070_P1G 0x03 |
50 | #define DIB0070S_P1A 0x02 | 50 | #define DIB0070S_P1A 0x02 |
51 | 51 | ||
52 | enum frontend_tune_state { | ||
53 | CT_TUNER_START = 10, | ||
54 | CT_TUNER_STEP_0, | ||
55 | CT_TUNER_STEP_1, | ||
56 | CT_TUNER_STEP_2, | ||
57 | CT_TUNER_STEP_3, | ||
58 | CT_TUNER_STEP_4, | ||
59 | CT_TUNER_STEP_5, | ||
60 | CT_TUNER_STEP_6, | ||
61 | CT_TUNER_STEP_7, | ||
62 | CT_TUNER_STOP, | ||
63 | }; | ||
64 | |||
65 | #define FE_CALLBACK_TIME_NEVER 0xffffffff | ||
66 | |||
67 | struct dib0070_state { | 52 | struct dib0070_state { |
68 | struct i2c_adapter *i2c; | 53 | struct i2c_adapter *i2c; |
69 | struct dvb_frontend *fe; | 54 | struct dvb_frontend *fe; |
@@ -71,10 +56,10 @@ struct dib0070_state { | |||
71 | u16 wbd_ff_offset; | 56 | u16 wbd_ff_offset; |
72 | u8 revision; | 57 | u8 revision; |
73 | 58 | ||
74 | enum frontend_tune_state tune_state; | 59 | enum frontend_tune_state tune_state; |
75 | u32 current_rf; | 60 | u32 current_rf; |
76 | 61 | ||
77 | /* for the captrim binary search */ | 62 | /* for the captrim binary search */ |
78 | s8 step; | 63 | s8 step; |
79 | u16 adc_diff; | 64 | u16 adc_diff; |
80 | 65 | ||
@@ -85,7 +70,7 @@ struct dib0070_state { | |||
85 | const struct dib0070_tuning *current_tune_table_index; | 70 | const struct dib0070_tuning *current_tune_table_index; |
86 | const struct dib0070_lna_match *lna_match; | 71 | const struct dib0070_lna_match *lna_match; |
87 | 72 | ||
88 | u8 wbd_gain_current; | 73 | u8 wbd_gain_current; |
89 | u16 wbd_offset_3_3[2]; | 74 | u16 wbd_offset_3_3[2]; |
90 | }; | 75 | }; |
91 | 76 | ||
@@ -93,8 +78,8 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) | |||
93 | { | 78 | { |
94 | u8 b[2]; | 79 | u8 b[2]; |
95 | struct i2c_msg msg[2] = { | 80 | struct i2c_msg msg[2] = { |
96 | {.addr = state->cfg->i2c_address,.flags = 0,.buf = ®,.len = 1}, | 81 | { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, |
97 | {.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2}, | 82 | { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, |
98 | }; | 83 | }; |
99 | if (i2c_transfer(state->i2c, msg, 2) != 2) { | 84 | if (i2c_transfer(state->i2c, msg, 2) != 2) { |
100 | printk(KERN_WARNING "DiB0070 I2C read failed\n"); | 85 | printk(KERN_WARNING "DiB0070 I2C read failed\n"); |
@@ -106,7 +91,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) | |||
106 | static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) | 91 | static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) |
107 | { | 92 | { |
108 | u8 b[3] = { reg, val >> 8, val & 0xff }; | 93 | u8 b[3] = { reg, val >> 8, val & 0xff }; |
109 | struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 }; | 94 | struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; |
110 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | 95 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { |
111 | printk(KERN_WARNING "DiB0070 I2C write failed\n"); | 96 | printk(KERN_WARNING "DiB0070 I2C write failed\n"); |
112 | return -EREMOTEIO; | 97 | return -EREMOTEIO; |
@@ -124,30 +109,30 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) | |||
124 | 109 | ||
125 | static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) | 110 | static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) |
126 | { | 111 | { |
127 | struct dib0070_state *state = fe->tuner_priv; | 112 | struct dib0070_state *state = fe->tuner_priv; |
128 | u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff; | 113 | u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff; |
129 | 114 | ||
130 | if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000) | 115 | if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000) |
131 | tmp |= (0 << 14); | 116 | tmp |= (0 << 14); |
132 | else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000) | 117 | else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000) |
133 | tmp |= (1 << 14); | 118 | tmp |= (1 << 14); |
134 | else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000) | 119 | else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000) |
135 | tmp |= (2 << 14); | 120 | tmp |= (2 << 14); |
136 | else | 121 | else |
137 | tmp |= (3 << 14); | 122 | tmp |= (3 << 14); |
138 | 123 | ||
139 | dib0070_write_reg(state, 0x02, tmp); | 124 | dib0070_write_reg(state, 0x02, tmp); |
140 | 125 | ||
141 | /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */ | 126 | /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */ |
142 | if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) { | 127 | if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) { |
143 | u16 value = dib0070_read_reg(state, 0x17); | 128 | u16 value = dib0070_read_reg(state, 0x17); |
144 | 129 | ||
145 | dib0070_write_reg(state, 0x17, value & 0xfffc); | 130 | dib0070_write_reg(state, 0x17, value & 0xfffc); |
146 | tmp = dib0070_read_reg(state, 0x01) & 0x01ff; | 131 | tmp = dib0070_read_reg(state, 0x01) & 0x01ff; |
147 | dib0070_write_reg(state, 0x01, tmp | (60 << 9)); | 132 | dib0070_write_reg(state, 0x01, tmp | (60 << 9)); |
148 | 133 | ||
149 | dib0070_write_reg(state, 0x17, value); | 134 | dib0070_write_reg(state, 0x17, value); |
150 | } | 135 | } |
151 | return 0; | 136 | return 0; |
152 | } | 137 | } |
153 | 138 | ||
@@ -160,14 +145,14 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state | |||
160 | if (*tune_state == CT_TUNER_STEP_0) { | 145 | if (*tune_state == CT_TUNER_STEP_0) { |
161 | 146 | ||
162 | dib0070_write_reg(state, 0x0f, 0xed10); | 147 | dib0070_write_reg(state, 0x0f, 0xed10); |
163 | dib0070_write_reg(state, 0x17, 0x0034); | 148 | dib0070_write_reg(state, 0x17, 0x0034); |
164 | 149 | ||
165 | dib0070_write_reg(state, 0x18, 0x0032); | 150 | dib0070_write_reg(state, 0x18, 0x0032); |
166 | state->step = state->captrim = state->fcaptrim = 64; | 151 | state->step = state->captrim = state->fcaptrim = 64; |
167 | state->adc_diff = 3000; | 152 | state->adc_diff = 3000; |
168 | ret = 20; | 153 | ret = 20; |
169 | 154 | ||
170 | *tune_state = CT_TUNER_STEP_1; | 155 | *tune_state = CT_TUNER_STEP_1; |
171 | } else if (*tune_state == CT_TUNER_STEP_1) { | 156 | } else if (*tune_state == CT_TUNER_STEP_1) { |
172 | state->step /= 2; | 157 | state->step /= 2; |
173 | dib0070_write_reg(state, 0x14, state->lo4 | state->captrim); | 158 | dib0070_write_reg(state, 0x14, state->lo4 | state->captrim); |
@@ -178,7 +163,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state | |||
178 | 163 | ||
179 | adc = dib0070_read_reg(state, 0x19); | 164 | adc = dib0070_read_reg(state, 0x19); |
180 | 165 | ||
181 | dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024); | 166 | dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024); |
182 | 167 | ||
183 | if (adc >= 400) { | 168 | if (adc >= 400) { |
184 | adc -= 400; | 169 | adc -= 400; |
@@ -193,6 +178,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state | |||
193 | state->adc_diff = adc; | 178 | state->adc_diff = adc; |
194 | state->fcaptrim = state->captrim; | 179 | state->fcaptrim = state->captrim; |
195 | 180 | ||
181 | |||
182 | |||
196 | } | 183 | } |
197 | state->captrim += (step_sign * state->step); | 184 | state->captrim += (step_sign * state->step); |
198 | 185 | ||
@@ -213,7 +200,7 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state | |||
213 | 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) | 200 | 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) |
214 | { | 201 | { |
215 | struct dib0070_state *state = fe->tuner_priv; | 202 | struct dib0070_state *state = fe->tuner_priv; |
216 | u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); | 203 | u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); |
217 | dprintk("CTRL_LO5: 0x%x", lo5); | 204 | dprintk("CTRL_LO5: 0x%x", lo5); |
218 | return dib0070_write_reg(state, 0x15, lo5); | 205 | return dib0070_write_reg(state, 0x15, lo5); |
219 | } | 206 | } |
@@ -227,99 +214,99 @@ void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open) | |||
227 | dib0070_write_reg(state, 0x1a, 0x0000); | 214 | dib0070_write_reg(state, 0x1a, 0x0000); |
228 | } else { | 215 | } else { |
229 | dib0070_write_reg(state, 0x1b, 0x4112); | 216 | dib0070_write_reg(state, 0x1b, 0x4112); |
230 | if (state->cfg->vga_filter != 0) { | 217 | if (state->cfg->vga_filter != 0) { |
231 | dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); | 218 | dib0070_write_reg(state, 0x1a, state->cfg->vga_filter); |
232 | dprintk("vga filter register is set to %x", state->cfg->vga_filter); | 219 | dprintk("vga filter register is set to %x", state->cfg->vga_filter); |
233 | } else | 220 | } else |
234 | dib0070_write_reg(state, 0x1a, 0x0009); | 221 | dib0070_write_reg(state, 0x1a, 0x0009); |
235 | } | 222 | } |
236 | } | 223 | } |
237 | 224 | ||
238 | EXPORT_SYMBOL(dib0070_ctrl_agc_filter); | 225 | EXPORT_SYMBOL(dib0070_ctrl_agc_filter); |
239 | struct dib0070_tuning { | 226 | struct dib0070_tuning { |
240 | u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ | 227 | u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ |
241 | u8 switch_trim; | 228 | u8 switch_trim; |
242 | u8 vco_band; | 229 | u8 vco_band; |
243 | u8 hfdiv; | 230 | u8 hfdiv; |
244 | u8 vco_multi; | 231 | u8 vco_multi; |
245 | u8 presc; | 232 | u8 presc; |
246 | u8 wbdmux; | 233 | u8 wbdmux; |
247 | u16 tuner_enable; | 234 | u16 tuner_enable; |
248 | }; | 235 | }; |
249 | 236 | ||
250 | struct dib0070_lna_match { | 237 | struct dib0070_lna_match { |
251 | u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ | 238 | u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ |
252 | u8 lna_band; | 239 | u8 lna_band; |
253 | }; | 240 | }; |
254 | 241 | ||
255 | static const struct dib0070_tuning dib0070s_tuning_table[] = { | 242 | static const struct dib0070_tuning dib0070s_tuning_table[] = { |
256 | {570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800}, /* UHF */ | 243 | { 570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */ |
257 | {700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800}, | 244 | { 700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 }, |
258 | {863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800}, | 245 | { 863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 }, |
259 | {1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND */ | 246 | { 1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */ |
260 | {1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, | 247 | { 1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, |
261 | {2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, | 248 | { 2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, |
262 | {0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000}, /* SBAND */ | 249 | { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */ |
263 | }; | 250 | }; |
264 | 251 | ||
265 | static const struct dib0070_tuning dib0070_tuning_table[] = { | 252 | static const struct dib0070_tuning dib0070_tuning_table[] = { |
266 | {115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000}, /* FM below 92MHz cannot be tuned */ | 253 | { 115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */ |
267 | {179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000}, /* VHF */ | 254 | { 179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */ |
268 | {189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000}, | 255 | { 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 }, |
269 | {250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000}, | 256 | { 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 }, |
270 | {569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800}, /* UHF */ | 257 | { 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 }, /* UHF */ |
271 | {699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800}, | 258 | { 699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800 }, |
272 | {863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800}, | 259 | { 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 }, |
273 | {0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND or everything higher than UHF */ | 260 | { 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */ |
274 | }; | 261 | }; |
275 | 262 | ||
276 | static const struct dib0070_lna_match dib0070_lna_flip_chip[] = { | 263 | static const struct dib0070_lna_match dib0070_lna_flip_chip[] = { |
277 | {180000, 0}, /* VHF */ | 264 | { 180000, 0 }, /* VHF */ |
278 | {188000, 1}, | 265 | { 188000, 1 }, |
279 | {196400, 2}, | 266 | { 196400, 2 }, |
280 | {250000, 3}, | 267 | { 250000, 3 }, |
281 | {550000, 0}, /* UHF */ | 268 | { 550000, 0 }, /* UHF */ |
282 | {590000, 1}, | 269 | { 590000, 1 }, |
283 | {666000, 3}, | 270 | { 666000, 3 }, |
284 | {864000, 5}, | 271 | { 864000, 5 }, |
285 | {1500000, 0}, /* LBAND or everything higher than UHF */ | 272 | { 1500000, 0 }, /* LBAND or everything higher than UHF */ |
286 | {1600000, 1}, | 273 | { 1600000, 1 }, |
287 | {2000000, 3}, | 274 | { 2000000, 3 }, |
288 | {0xffffffff, 7}, | 275 | { 0xffffffff, 7 }, |
289 | }; | 276 | }; |
290 | 277 | ||
291 | static const struct dib0070_lna_match dib0070_lna[] = { | 278 | static const struct dib0070_lna_match dib0070_lna[] = { |
292 | {180000, 0}, /* VHF */ | 279 | { 180000, 0 }, /* VHF */ |
293 | {188000, 1}, | 280 | { 188000, 1 }, |
294 | {196400, 2}, | 281 | { 196400, 2 }, |
295 | {250000, 3}, | 282 | { 250000, 3 }, |
296 | {550000, 2}, /* UHF */ | 283 | { 550000, 2 }, /* UHF */ |
297 | {650000, 3}, | 284 | { 650000, 3 }, |
298 | {750000, 5}, | 285 | { 750000, 5 }, |
299 | {850000, 6}, | 286 | { 850000, 6 }, |
300 | {864000, 7}, | 287 | { 864000, 7 }, |
301 | {1500000, 0}, /* LBAND or everything higher than UHF */ | 288 | { 1500000, 0 }, /* LBAND or everything higher than UHF */ |
302 | {1600000, 1}, | 289 | { 1600000, 1 }, |
303 | {2000000, 3}, | 290 | { 2000000, 3 }, |
304 | {0xffffffff, 7}, | 291 | { 0xffffffff, 7 }, |
305 | }; | 292 | }; |
306 | 293 | ||
307 | #define LPF 100 // define for the loop filter 100kHz by default 16-07-06 | 294 | #define LPF 100 |
308 | static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) | 295 | static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) |
309 | { | 296 | { |
310 | struct dib0070_state *state = fe->tuner_priv; | 297 | struct dib0070_state *state = fe->tuner_priv; |
311 | 298 | ||
312 | const struct dib0070_tuning *tune; | 299 | const struct dib0070_tuning *tune; |
313 | const struct dib0070_lna_match *lna_match; | 300 | const struct dib0070_lna_match *lna_match; |
314 | 301 | ||
315 | enum frontend_tune_state *tune_state = &state->tune_state; | 302 | enum frontend_tune_state *tune_state = &state->tune_state; |
316 | int ret = 10; /* 1ms is the default delay most of the time */ | 303 | int ret = 10; /* 1ms is the default delay most of the time */ |
317 | 304 | ||
318 | u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000); | 305 | u8 band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000); |
319 | u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf); | 306 | u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf); |
320 | 307 | ||
321 | #ifdef CONFIG_SYS_ISDBT | 308 | #ifdef CONFIG_SYS_ISDBT |
322 | if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) | 309 | if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) |
323 | if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) | 310 | if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) |
324 | && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) | 311 | && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) |
325 | || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) | 312 | || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) |
@@ -328,172 +315,180 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par | |||
328 | && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))) | 315 | && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))) |
329 | freq += 850; | 316 | freq += 850; |
330 | #endif | 317 | #endif |
318 | if (state->current_rf != freq) { | ||
319 | |||
320 | switch (state->revision) { | ||
321 | case DIB0070S_P1A: | ||
322 | tune = dib0070s_tuning_table; | ||
323 | lna_match = dib0070_lna; | ||
324 | break; | ||
325 | default: | ||
326 | tune = dib0070_tuning_table; | ||
327 | if (state->cfg->flip_chip) | ||
328 | lna_match = dib0070_lna_flip_chip; | ||
329 | else | ||
330 | lna_match = dib0070_lna; | ||
331 | break; | ||
332 | } | ||
333 | while (freq > tune->max_freq) /* find the right one */ | ||
334 | tune++; | ||
335 | while (freq > lna_match->max_freq) /* find the right one */ | ||
336 | lna_match++; | ||
337 | |||
338 | state->current_tune_table_index = tune; | ||
339 | state->lna_match = lna_match; | ||
340 | } | ||
341 | |||
342 | if (*tune_state == CT_TUNER_START) { | ||
343 | dprintk("Tuning for Band: %hd (%d kHz)", band, freq); | ||
331 | if (state->current_rf != freq) { | 344 | if (state->current_rf != freq) { |
345 | u8 REFDIV; | ||
346 | u32 FBDiv, Rest, FREF, VCOF_kHz; | ||
347 | u8 Den; | ||
348 | |||
349 | state->current_rf = freq; | ||
350 | state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7); | ||
351 | |||
352 | |||
353 | dib0070_write_reg(state, 0x17, 0x30); | ||
354 | |||
355 | |||
356 | VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2; | ||
357 | |||
358 | switch (band) { | ||
359 | case BAND_VHF: | ||
360 | REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000); | ||
361 | break; | ||
362 | case BAND_FM: | ||
363 | REFDIV = (u8) ((state->cfg->clock_khz) / 1000); | ||
364 | break; | ||
365 | default: | ||
366 | REFDIV = (u8) (state->cfg->clock_khz / 10000); | ||
367 | break; | ||
368 | } | ||
369 | FREF = state->cfg->clock_khz / REFDIV; | ||
370 | |||
371 | |||
332 | 372 | ||
333 | switch (state->revision) { | 373 | switch (state->revision) { |
334 | case DIB0070S_P1A: | 374 | case DIB0070S_P1A: |
335 | tune = dib0070s_tuning_table; | 375 | FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF); |
336 | lna_match = dib0070_lna; | 376 | Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF; |
337 | break; | 377 | break; |
378 | |||
379 | case DIB0070_P1G: | ||
380 | case DIB0070_P1F: | ||
338 | default: | 381 | default: |
339 | tune = dib0070_tuning_table; | 382 | FBDiv = (freq / (FREF / 2)); |
340 | if (state->cfg->flip_chip) | 383 | Rest = 2 * freq - FBDiv * FREF; |
341 | lna_match = dib0070_lna_flip_chip; | ||
342 | else | ||
343 | lna_match = dib0070_lna; | ||
344 | break; | 384 | break; |
345 | } | 385 | } |
346 | while (freq > tune->max_freq) /* find the right one */ | ||
347 | tune++; | ||
348 | while (freq > lna_match->max_freq) /* find the right one */ | ||
349 | lna_match++; | ||
350 | 386 | ||
351 | state->current_tune_table_index = tune; | 387 | if (Rest < LPF) |
352 | state->lna_match = lna_match; | 388 | Rest = 0; |
353 | } | 389 | else if (Rest < 2 * LPF) |
390 | Rest = 2 * LPF; | ||
391 | else if (Rest > (FREF - LPF)) { | ||
392 | Rest = 0; | ||
393 | FBDiv += 1; | ||
394 | } else if (Rest > (FREF - 2 * LPF)) | ||
395 | Rest = FREF - 2 * LPF; | ||
396 | Rest = (Rest * 6528) / (FREF / 10); | ||
397 | |||
398 | Den = 1; | ||
399 | if (Rest > 0) { | ||
400 | state->lo4 |= (1 << 14) | (1 << 12); | ||
401 | Den = 255; | ||
402 | } | ||
403 | |||
354 | 404 | ||
355 | if (*tune_state == CT_TUNER_START) { | 405 | dib0070_write_reg(state, 0x11, (u16)FBDiv); |
356 | dprintk("Tuning for Band: %hd (%d kHz)", band, freq); | 406 | dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV); |
357 | if (state->current_rf != freq) { | 407 | dib0070_write_reg(state, 0x13, (u16) Rest); |
358 | u8 REFDIV; | 408 | |
359 | u32 FBDiv, Rest, FREF, VCOF_kHz; | 409 | if (state->revision == DIB0070S_P1A) { |
360 | u8 Den; | 410 | |
361 | 411 | if (band == BAND_SBAND) { | |
362 | state->current_rf = freq; | 412 | dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); |
363 | state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7); | 413 | dib0070_write_reg(state, 0x1d, 0xFFFF); |
364 | 414 | } else | |
365 | dib0070_write_reg(state, 0x17, 0x30); | 415 | dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1); |
366 | |||
367 | VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2; | ||
368 | |||
369 | switch (band) { | ||
370 | case BAND_VHF: | ||
371 | REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000); | ||
372 | break; | ||
373 | case BAND_FM: | ||
374 | REFDIV = (u8) ((state->cfg->clock_khz) / 1000); | ||
375 | break; | ||
376 | default: | ||
377 | REFDIV = (u8) (state->cfg->clock_khz / 10000); | ||
378 | break; | ||
379 | } | ||
380 | FREF = state->cfg->clock_khz / REFDIV; | ||
381 | |||
382 | switch (state->revision) { | ||
383 | case DIB0070S_P1A: | ||
384 | FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF); | ||
385 | Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF; | ||
386 | break; | ||
387 | |||
388 | case DIB0070_P1G: | ||
389 | case DIB0070_P1F: | ||
390 | default: | ||
391 | FBDiv = (freq / (FREF / 2)); | ||
392 | Rest = 2 * freq - FBDiv * FREF; | ||
393 | break; | ||
394 | } | ||
395 | |||
396 | if (Rest < LPF) | ||
397 | Rest = 0; | ||
398 | else if (Rest < 2 * LPF) | ||
399 | Rest = 2 * LPF; | ||
400 | else if (Rest > (FREF - LPF)) { | ||
401 | Rest = 0; | ||
402 | FBDiv += 1; | ||
403 | } else if (Rest > (FREF - 2 * LPF)) | ||
404 | Rest = FREF - 2 * LPF; | ||
405 | Rest = (Rest * 6528) / (FREF / 10); | ||
406 | |||
407 | Den = 1; | ||
408 | if (Rest > 0) { | ||
409 | state->lo4 |= (1 << 14) | (1 << 12); | ||
410 | Den = 255; | ||
411 | } | ||
412 | |||
413 | dib0070_write_reg(state, 0x11, (u16) FBDiv); | ||
414 | dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV); | ||
415 | dib0070_write_reg(state, 0x13, (u16) Rest); | ||
416 | |||
417 | if (state->revision == DIB0070S_P1A) { | ||
418 | |||
419 | if (band == BAND_SBAND) { | ||
420 | dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); | ||
421 | dib0070_write_reg(state, 0x1d, 0xFFFF); | ||
422 | } else | ||
423 | dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1); | ||
424 | } | ||
425 | |||
426 | dib0070_write_reg(state, 0x20, | ||
427 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable); | ||
428 | |||
429 | dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF); | ||
430 | dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest); | ||
431 | dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1); | ||
432 | dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv); | ||
433 | dprintk("VCO = %hd", state->current_tune_table_index->vco_band); | ||
434 | dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); | ||
435 | |||
436 | *tune_state = CT_TUNER_STEP_0; | ||
437 | } else { /* we are already tuned to this frequency - the configuration is correct */ | ||
438 | ret = 50; /* wakeup time */ | ||
439 | *tune_state = CT_TUNER_STEP_5; | ||
440 | } | 416 | } |
441 | } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) { | ||
442 | 417 | ||
443 | ret = dib0070_captrim(state, tune_state); | 418 | dib0070_write_reg(state, 0x20, |
419 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable); | ||
444 | 420 | ||
445 | } else if (*tune_state == CT_TUNER_STEP_4) { | 421 | dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF); |
446 | const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; | 422 | dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest); |
447 | if (tmp != NULL) { | 423 | dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1); |
448 | while (freq / 1000 > tmp->freq) /* find the right one */ | 424 | dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv); |
449 | tmp++; | 425 | dprintk("VCO = %hd", state->current_tune_table_index->vco_band); |
450 | dib0070_write_reg(state, 0x0f, | 426 | dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq); |
451 | (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state-> | 427 | |
452 | current_tune_table_index-> | 428 | *tune_state = CT_TUNER_STEP_0; |
453 | wbdmux << 0)); | 429 | } else { /* we are already tuned to this frequency - the configuration is correct */ |
454 | state->wbd_gain_current = tmp->wbd_gain_val; | 430 | ret = 50; /* wakeup time */ |
455 | } else { | 431 | *tune_state = CT_TUNER_STEP_5; |
432 | } | ||
433 | } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) { | ||
434 | |||
435 | ret = dib0070_captrim(state, tune_state); | ||
436 | |||
437 | } else if (*tune_state == CT_TUNER_STEP_4) { | ||
438 | const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; | ||
439 | if (tmp != NULL) { | ||
440 | while (freq/1000 > tmp->freq) /* find the right one */ | ||
441 | tmp++; | ||
442 | dib0070_write_reg(state, 0x0f, | ||
443 | (0 << 15) | (1 << 14) | (3 << 12) | ||
444 | | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | ||
445 | | (state->current_tune_table_index->wbdmux << 0)); | ||
446 | state->wbd_gain_current = tmp->wbd_gain_val; | ||
447 | } else { | ||
456 | dib0070_write_reg(state, 0x0f, | 448 | dib0070_write_reg(state, 0x0f, |
457 | (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index-> | 449 | (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index-> |
458 | wbdmux << 0)); | 450 | wbdmux << 0)); |
459 | state->wbd_gain_current = 6; | 451 | state->wbd_gain_current = 6; |
460 | } | 452 | } |
461 | 453 | ||
462 | dib0070_write_reg(state, 0x06, 0x3fff); | 454 | dib0070_write_reg(state, 0x06, 0x3fff); |
463 | dib0070_write_reg(state, 0x07, | 455 | dib0070_write_reg(state, 0x07, |
464 | (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0)); | 456 | (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0)); |
465 | dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127)); | 457 | dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127)); |
466 | dib0070_write_reg(state, 0x0d, 0x0d80); | 458 | dib0070_write_reg(state, 0x0d, 0x0d80); |
467 | 459 | ||
468 | dib0070_write_reg(state, 0x18, 0x07ff); | ||
469 | dib0070_write_reg(state, 0x17, 0x0033); | ||
470 | 460 | ||
471 | *tune_state = CT_TUNER_STEP_5; | 461 | dib0070_write_reg(state, 0x18, 0x07ff); |
472 | } else if (*tune_state == CT_TUNER_STEP_5) { | 462 | dib0070_write_reg(state, 0x17, 0x0033); |
473 | dib0070_set_bandwidth(fe, ch); | 463 | |
474 | *tune_state = CT_TUNER_STOP; | 464 | |
475 | } else { | 465 | *tune_state = CT_TUNER_STEP_5; |
476 | ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */ | 466 | } else if (*tune_state == CT_TUNER_STEP_5) { |
477 | } | 467 | dib0070_set_bandwidth(fe, ch); |
478 | return ret; | 468 | *tune_state = CT_TUNER_STOP; |
469 | } else { | ||
470 | ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */ | ||
471 | } | ||
472 | return ret; | ||
479 | } | 473 | } |
480 | 474 | ||
475 | |||
481 | static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | 476 | static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) |
482 | { | 477 | { |
483 | struct dib0070_state *state = fe->tuner_priv; | 478 | struct dib0070_state *state = fe->tuner_priv; |
484 | uint32_t ret; | 479 | uint32_t ret; |
485 | 480 | ||
486 | state->tune_state = CT_TUNER_START; | 481 | state->tune_state = CT_TUNER_START; |
487 | 482 | ||
488 | do { | 483 | do { |
489 | ret = dib0070_tune_digital(fe, p); | 484 | ret = dib0070_tune_digital(fe, p); |
490 | if (ret != FE_CALLBACK_TIME_NEVER) | 485 | if (ret != FE_CALLBACK_TIME_NEVER) |
491 | msleep(ret / 10); | 486 | msleep(ret/10); |
492 | else | 487 | else |
493 | break; | 488 | break; |
494 | } while (state->tune_state != CT_TUNER_STOP); | 489 | } while (state->tune_state != CT_TUNER_STOP); |
495 | 490 | ||
496 | return 0; | 491 | return 0; |
497 | } | 492 | } |
498 | 493 | ||
499 | static int dib0070_wakeup(struct dvb_frontend *fe) | 494 | static int dib0070_wakeup(struct dvb_frontend *fe) |
@@ -512,92 +507,113 @@ static int dib0070_sleep(struct dvb_frontend *fe) | |||
512 | return 0; | 507 | return 0; |
513 | } | 508 | } |
514 | 509 | ||
515 | static const u16 dib0070_p1f_defaults[] = { | 510 | u8 dib0070_get_rf_output(struct dvb_frontend *fe) |
511 | { | ||
512 | struct dib0070_state *state = fe->tuner_priv; | ||
513 | return (dib0070_read_reg(state, 0x07) >> 11) & 0x3; | ||
514 | } | ||
515 | EXPORT_SYMBOL(dib0070_get_rf_output); | ||
516 | |||
517 | int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no) | ||
518 | { | ||
519 | struct dib0070_state *state = fe->tuner_priv; | ||
520 | u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff; | ||
521 | if (no > 3) | ||
522 | no = 3; | ||
523 | if (no < 1) | ||
524 | no = 1; | ||
525 | return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11)); | ||
526 | } | ||
527 | EXPORT_SYMBOL(dib0070_set_rf_output); | ||
528 | |||
529 | static const u16 dib0070_p1f_defaults[] = | ||
530 | |||
531 | { | ||
516 | 7, 0x02, | 532 | 7, 0x02, |
517 | 0x0008, | 533 | 0x0008, |
518 | 0x0000, | 534 | 0x0000, |
519 | 0x0000, | 535 | 0x0000, |
520 | 0x0000, | 536 | 0x0000, |
521 | 0x0000, | 537 | 0x0000, |
522 | 0x0002, | 538 | 0x0002, |
523 | 0x0100, | 539 | 0x0100, |
524 | 540 | ||
525 | 3, 0x0d, | 541 | 3, 0x0d, |
526 | 0x0d80, | 542 | 0x0d80, |
527 | 0x0001, | 543 | 0x0001, |
528 | 0x0000, | 544 | 0x0000, |
529 | 545 | ||
530 | 4, 0x11, | 546 | 4, 0x11, |
531 | 0x0000, | 547 | 0x0000, |
532 | 0x0103, | 548 | 0x0103, |
533 | 0x0000, | 549 | 0x0000, |
534 | 0x0000, | 550 | 0x0000, |
535 | 551 | ||
536 | 3, 0x16, | 552 | 3, 0x16, |
537 | 0x0004 | 0x0040, | 553 | 0x0004 | 0x0040, |
538 | 0x0030, | 554 | 0x0030, |
539 | 0x07ff, | 555 | 0x07ff, |
540 | 556 | ||
541 | 6, 0x1b, | 557 | 6, 0x1b, |
542 | 0x4112, | 558 | 0x4112, |
543 | 0xff00, | 559 | 0xff00, |
544 | 0xc07f, | 560 | 0xc07f, |
545 | 0x0000, | 561 | 0x0000, |
546 | 0x0180, | 562 | 0x0180, |
547 | 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, | 563 | 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, |
548 | 564 | ||
549 | 0, | 565 | 0, |
550 | }; | 566 | }; |
551 | 567 | ||
552 | static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain) | 568 | static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain) |
553 | { | 569 | { |
554 | u16 tuner_en = dib0070_read_reg(state, 0x20); | 570 | u16 tuner_en = dib0070_read_reg(state, 0x20); |
555 | u16 offset; | 571 | u16 offset; |
556 | 572 | ||
557 | dib0070_write_reg(state, 0x18, 0x07ff); | 573 | dib0070_write_reg(state, 0x18, 0x07ff); |
558 | dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); | 574 | dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); |
559 | dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0)); | 575 | dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0)); |
560 | msleep(9); | 576 | msleep(9); |
561 | offset = dib0070_read_reg(state, 0x19); | 577 | offset = dib0070_read_reg(state, 0x19); |
562 | dib0070_write_reg(state, 0x20, tuner_en); | 578 | dib0070_write_reg(state, 0x20, tuner_en); |
563 | return offset; | 579 | return offset; |
564 | } | 580 | } |
565 | 581 | ||
566 | static void dib0070_wbd_offset_calibration(struct dib0070_state *state) | 582 | static void dib0070_wbd_offset_calibration(struct dib0070_state *state) |
567 | { | 583 | { |
568 | u8 gain; | 584 | u8 gain; |
569 | for (gain = 6; gain < 8; gain++) { | 585 | for (gain = 6; gain < 8; gain++) { |
570 | state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2); | 586 | state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2); |
571 | dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]); | 587 | dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]); |
572 | } | 588 | } |
573 | } | 589 | } |
574 | 590 | ||
575 | u16 dib0070_wbd_offset(struct dvb_frontend *fe) | 591 | u16 dib0070_wbd_offset(struct dvb_frontend *fe) |
576 | { | 592 | { |
577 | struct dib0070_state *state = fe->tuner_priv; | 593 | struct dib0070_state *state = fe->tuner_priv; |
578 | const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; | 594 | const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain; |
579 | u32 freq = fe->dtv_property_cache.frequency / 1000; | 595 | u32 freq = fe->dtv_property_cache.frequency/1000; |
580 | 596 | ||
581 | if (tmp != NULL) { | 597 | if (tmp != NULL) { |
582 | while (freq / 1000 > tmp->freq) /* find the right one */ | 598 | while (freq/1000 > tmp->freq) /* find the right one */ |
583 | tmp++; | 599 | tmp++; |
584 | state->wbd_gain_current = tmp->wbd_gain_val; | 600 | state->wbd_gain_current = tmp->wbd_gain_val; |
585 | } else | 601 | } else |
586 | state->wbd_gain_current = 6; | 602 | state->wbd_gain_current = 6; |
587 | 603 | ||
588 | return state->wbd_offset_3_3[state->wbd_gain_current - 6]; | 604 | return state->wbd_offset_3_3[state->wbd_gain_current - 6]; |
589 | } | 605 | } |
590 | |||
591 | EXPORT_SYMBOL(dib0070_wbd_offset); | 606 | EXPORT_SYMBOL(dib0070_wbd_offset); |
592 | 607 | ||
593 | #define pgm_read_word(w) (*w) | 608 | #define pgm_read_word(w) (*w) |
594 | static int dib0070_reset(struct dvb_frontend *fe) | 609 | static int dib0070_reset(struct dvb_frontend *fe) |
595 | { | 610 | { |
596 | struct dib0070_state *state = fe->tuner_priv; | 611 | struct dib0070_state *state = fe->tuner_priv; |
597 | u16 l, r, *n; | 612 | u16 l, r, *n; |
598 | 613 | ||
599 | HARD_RESET(state); | 614 | HARD_RESET(state); |
600 | 615 | ||
616 | |||
601 | #ifndef FORCE_SBAND_TUNER | 617 | #ifndef FORCE_SBAND_TUNER |
602 | if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1) | 618 | if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1) |
603 | state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff; | 619 | state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff; |
@@ -605,7 +621,7 @@ static int dib0070_reset(struct dvb_frontend *fe) | |||
605 | #else | 621 | #else |
606 | #warning forcing SBAND | 622 | #warning forcing SBAND |
607 | #endif | 623 | #endif |
608 | state->revision = DIB0070S_P1A; | 624 | state->revision = DIB0070S_P1A; |
609 | 625 | ||
610 | /* P1F or not */ | 626 | /* P1F or not */ |
611 | dprintk("Revision: %x", state->revision); | 627 | dprintk("Revision: %x", state->revision); |
@@ -620,7 +636,7 @@ static int dib0070_reset(struct dvb_frontend *fe) | |||
620 | while (l) { | 636 | while (l) { |
621 | r = pgm_read_word(n++); | 637 | r = pgm_read_word(n++); |
622 | do { | 638 | do { |
623 | dib0070_write_reg(state, (u8) r, pgm_read_word(n++)); | 639 | dib0070_write_reg(state, (u8)r, pgm_read_word(n++)); |
624 | r++; | 640 | r++; |
625 | } while (--l); | 641 | } while (--l); |
626 | l = pgm_read_word(n++); | 642 | l = pgm_read_word(n++); |
@@ -633,6 +649,7 @@ static int dib0070_reset(struct dvb_frontend *fe) | |||
633 | else | 649 | else |
634 | r = 2; | 650 | r = 2; |
635 | 651 | ||
652 | |||
636 | r |= state->cfg->osc_buffer_state << 3; | 653 | r |= state->cfg->osc_buffer_state << 3; |
637 | 654 | ||
638 | dib0070_write_reg(state, 0x10, r); | 655 | dib0070_write_reg(state, 0x10, r); |
@@ -643,16 +660,24 @@ static int dib0070_reset(struct dvb_frontend *fe) | |||
643 | dib0070_write_reg(state, 0x02, r | (1 << 5)); | 660 | dib0070_write_reg(state, 0x02, r | (1 << 5)); |
644 | } | 661 | } |
645 | 662 | ||
646 | if (state->revision == DIB0070S_P1A) | 663 | if (state->revision == DIB0070S_P1A) |
647 | dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); | 664 | dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0); |
648 | else | 665 | else |
649 | dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter); | 666 | dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter); |
650 | 667 | ||
651 | dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); | 668 | dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); |
652 | 669 | ||
653 | dib0070_wbd_offset_calibration(state); | 670 | dib0070_wbd_offset_calibration(state); |
654 | 671 | ||
655 | return 0; | 672 | return 0; |
673 | } | ||
674 | |||
675 | static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
676 | { | ||
677 | struct dib0070_state *state = fe->tuner_priv; | ||
678 | |||
679 | *frequency = 1000 * state->current_rf; | ||
680 | return 0; | ||
656 | } | 681 | } |
657 | 682 | ||
658 | static int dib0070_release(struct dvb_frontend *fe) | 683 | static int dib0070_release(struct dvb_frontend *fe) |
@@ -664,18 +689,18 @@ static int dib0070_release(struct dvb_frontend *fe) | |||
664 | 689 | ||
665 | static const struct dvb_tuner_ops dib0070_ops = { | 690 | static const struct dvb_tuner_ops dib0070_ops = { |
666 | .info = { | 691 | .info = { |
667 | .name = "DiBcom DiB0070", | 692 | .name = "DiBcom DiB0070", |
668 | .frequency_min = 45000000, | 693 | .frequency_min = 45000000, |
669 | .frequency_max = 860000000, | 694 | .frequency_max = 860000000, |
670 | .frequency_step = 1000, | 695 | .frequency_step = 1000, |
671 | }, | 696 | }, |
672 | .release = dib0070_release, | 697 | .release = dib0070_release, |
673 | 698 | ||
674 | .init = dib0070_wakeup, | 699 | .init = dib0070_wakeup, |
675 | .sleep = dib0070_sleep, | 700 | .sleep = dib0070_sleep, |
676 | .set_params = dib0070_tune, | 701 | .set_params = dib0070_tune, |
677 | 702 | ||
678 | // .get_frequency = dib0070_get_frequency, | 703 | .get_frequency = dib0070_get_frequency, |
679 | // .get_bandwidth = dib0070_get_bandwidth | 704 | // .get_bandwidth = dib0070_get_bandwidth |
680 | }; | 705 | }; |
681 | 706 | ||
@@ -687,7 +712,7 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter | |||
687 | 712 | ||
688 | state->cfg = cfg; | 713 | state->cfg = cfg; |
689 | state->i2c = i2c; | 714 | state->i2c = i2c; |
690 | state->fe = fe; | 715 | state->fe = fe; |
691 | fe->tuner_priv = state; | 716 | fe->tuner_priv = state; |
692 | 717 | ||
693 | if (dib0070_reset(fe) != 0) | 718 | if (dib0070_reset(fe) != 0) |
@@ -699,12 +724,11 @@ struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter | |||
699 | fe->tuner_priv = state; | 724 | fe->tuner_priv = state; |
700 | return fe; | 725 | return fe; |
701 | 726 | ||
702 | free_mem: | 727 | free_mem: |
703 | kfree(state); | 728 | kfree(state); |
704 | fe->tuner_priv = NULL; | 729 | fe->tuner_priv = NULL; |
705 | return NULL; | 730 | return NULL; |
706 | } | 731 | } |
707 | |||
708 | EXPORT_SYMBOL(dib0070_attach); | 732 | EXPORT_SYMBOL(dib0070_attach); |
709 | 733 | ||
710 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); | 734 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); |
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h index eec9e52ffa7..45c31fae396 100644 --- a/drivers/media/dvb/frontends/dib0070.h +++ b/drivers/media/dvb/frontends/dib0070.h | |||
@@ -52,6 +52,8 @@ struct dib0070_config { | |||
52 | extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); | 52 | extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); |
53 | extern u16 dib0070_wbd_offset(struct dvb_frontend *); | 53 | extern u16 dib0070_wbd_offset(struct dvb_frontend *); |
54 | extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open); | 54 | extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open); |
55 | extern u8 dib0070_get_rf_output(struct dvb_frontend *fe); | ||
56 | extern int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no); | ||
55 | #else | 57 | #else |
56 | static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) | 58 | static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) |
57 | { | 59 | { |
@@ -62,7 +64,7 @@ static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struc | |||
62 | static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe) | 64 | static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe) |
63 | { | 65 | { |
64 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 66 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
65 | return -ENODEV; | 67 | return 0; |
66 | } | 68 | } |
67 | 69 | ||
68 | static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open) | 70 | static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open) |
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c new file mode 100644 index 00000000000..614552709a6 --- /dev/null +++ b/drivers/media/dvb/frontends/dib0090.c | |||
@@ -0,0 +1,1522 @@ | |||
1 | /* | ||
2 | * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner. | ||
3 | * | ||
4 | * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation; either version 2 of the | ||
9 | * License, or (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | * | ||
22 | * This code is more or less generated from another driver, please | ||
23 | * excuse some codingstyle oddities. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/i2c.h> | ||
29 | |||
30 | #include "dvb_frontend.h" | ||
31 | |||
32 | #include "dib0090.h" | ||
33 | #include "dibx000_common.h" | ||
34 | |||
35 | static int debug; | ||
36 | module_param(debug, int, 0644); | ||
37 | MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); | ||
38 | |||
39 | #define dprintk(args...) do { \ | ||
40 | if (debug) { \ | ||
41 | printk(KERN_DEBUG "DiB0090: "); \ | ||
42 | printk(args); \ | ||
43 | printk("\n"); \ | ||
44 | } \ | ||
45 | } while (0) | ||
46 | |||
47 | #define CONFIG_SYS_ISDBT | ||
48 | #define CONFIG_BAND_CBAND | ||
49 | #define CONFIG_BAND_VHF | ||
50 | #define CONFIG_BAND_UHF | ||
51 | #define CONFIG_DIB0090_USE_PWM_AGC | ||
52 | |||
53 | #define EN_LNA0 0x8000 | ||
54 | #define EN_LNA1 0x4000 | ||
55 | #define EN_LNA2 0x2000 | ||
56 | #define EN_LNA3 0x1000 | ||
57 | #define EN_MIX0 0x0800 | ||
58 | #define EN_MIX1 0x0400 | ||
59 | #define EN_MIX2 0x0200 | ||
60 | #define EN_MIX3 0x0100 | ||
61 | #define EN_IQADC 0x0040 | ||
62 | #define EN_PLL 0x0020 | ||
63 | #define EN_TX 0x0010 | ||
64 | #define EN_BB 0x0008 | ||
65 | #define EN_LO 0x0004 | ||
66 | #define EN_BIAS 0x0001 | ||
67 | |||
68 | #define EN_IQANA 0x0002 | ||
69 | #define EN_DIGCLK 0x0080 /* not in the 0x24 reg, only in 0x1b */ | ||
70 | #define EN_CRYSTAL 0x0002 | ||
71 | |||
72 | #define EN_UHF 0x22E9 | ||
73 | #define EN_VHF 0x44E9 | ||
74 | #define EN_LBD 0x11E9 | ||
75 | #define EN_SBD 0x44E9 | ||
76 | #define EN_CAB 0x88E9 | ||
77 | |||
78 | #define pgm_read_word(w) (*w) | ||
79 | |||
80 | struct dc_calibration; | ||
81 | |||
82 | struct dib0090_tuning { | ||
83 | u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ | ||
84 | u8 switch_trim; | ||
85 | u8 lna_tune; | ||
86 | u8 lna_bias; | ||
87 | u16 v2i; | ||
88 | u16 mix; | ||
89 | u16 load; | ||
90 | u16 tuner_enable; | ||
91 | }; | ||
92 | |||
93 | struct dib0090_pll { | ||
94 | u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ | ||
95 | u8 vco_band; | ||
96 | u8 hfdiv_code; | ||
97 | u8 hfdiv; | ||
98 | u8 topresc; | ||
99 | }; | ||
100 | |||
101 | struct dib0090_state { | ||
102 | struct i2c_adapter *i2c; | ||
103 | struct dvb_frontend *fe; | ||
104 | const struct dib0090_config *config; | ||
105 | |||
106 | u8 current_band; | ||
107 | u16 revision; | ||
108 | enum frontend_tune_state tune_state; | ||
109 | u32 current_rf; | ||
110 | |||
111 | u16 wbd_offset; | ||
112 | s16 wbd_target; /* in dB */ | ||
113 | |||
114 | s16 rf_gain_limit; /* take-over-point: where to split between bb and rf gain */ | ||
115 | s16 current_gain; /* keeps the currently programmed gain */ | ||
116 | u8 agc_step; /* new binary search */ | ||
117 | |||
118 | u16 gain[2]; /* for channel monitoring */ | ||
119 | |||
120 | const u16 *rf_ramp; | ||
121 | const u16 *bb_ramp; | ||
122 | |||
123 | /* for the software AGC ramps */ | ||
124 | u16 bb_1_def; | ||
125 | u16 rf_lt_def; | ||
126 | u16 gain_reg[4]; | ||
127 | |||
128 | /* for the captrim/dc-offset search */ | ||
129 | s8 step; | ||
130 | s16 adc_diff; | ||
131 | s16 min_adc_diff; | ||
132 | |||
133 | s8 captrim; | ||
134 | s8 fcaptrim; | ||
135 | |||
136 | const struct dc_calibration *dc; | ||
137 | u16 bb6, bb7; | ||
138 | |||
139 | const struct dib0090_tuning *current_tune_table_index; | ||
140 | const struct dib0090_pll *current_pll_table_index; | ||
141 | |||
142 | u8 tuner_is_tuned; | ||
143 | u8 agc_freeze; | ||
144 | |||
145 | u8 reset; | ||
146 | }; | ||
147 | |||
148 | static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) | ||
149 | { | ||
150 | u8 b[2]; | ||
151 | struct i2c_msg msg[2] = { | ||
152 | {.addr = state->config->i2c_address, .flags = 0, .buf = ®, .len = 1}, | ||
153 | {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2}, | ||
154 | }; | ||
155 | if (i2c_transfer(state->i2c, msg, 2) != 2) { | ||
156 | printk(KERN_WARNING "DiB0090 I2C read failed\n"); | ||
157 | return 0; | ||
158 | } | ||
159 | return (b[0] << 8) | b[1]; | ||
160 | } | ||
161 | |||
162 | static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) | ||
163 | { | ||
164 | u8 b[3] = { reg & 0xff, val >> 8, val & 0xff }; | ||
165 | struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 }; | ||
166 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | ||
167 | printk(KERN_WARNING "DiB0090 I2C write failed\n"); | ||
168 | return -EREMOTEIO; | ||
169 | } | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | #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) | ||
174 | #define ADC_TARGET -220 | ||
175 | #define GAIN_ALPHA 5 | ||
176 | #define WBD_ALPHA 6 | ||
177 | #define LPF 100 | ||
178 | static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c) | ||
179 | { | ||
180 | do { | ||
181 | dib0090_write_reg(state, r++, *b++); | ||
182 | } while (--c); | ||
183 | } | ||
184 | |||
185 | static u16 dib0090_identify(struct dvb_frontend *fe) | ||
186 | { | ||
187 | struct dib0090_state *state = fe->tuner_priv; | ||
188 | u16 v; | ||
189 | |||
190 | v = dib0090_read_reg(state, 0x1a); | ||
191 | |||
192 | #ifdef FIRMWARE_FIREFLY | ||
193 | /* pll is not locked locked */ | ||
194 | if (!(v & 0x800)) | ||
195 | dprintk("FE%d : Identification : pll is not yet locked", fe->id); | ||
196 | #endif | ||
197 | |||
198 | /* without PLL lock info */ | ||
199 | v &= 0x3ff; | ||
200 | dprintk("P/V: %04x:", v); | ||
201 | |||
202 | if ((v >> 8) & 0xf) | ||
203 | dprintk("FE%d : Product ID = 0x%x : KROSUS", fe->id, (v >> 8) & 0xf); | ||
204 | else | ||
205 | return 0xff; | ||
206 | |||
207 | v &= 0xff; | ||
208 | if (((v >> 5) & 0x7) == 0x1) | ||
209 | dprintk("FE%d : MP001 : 9090/8096", fe->id); | ||
210 | else if (((v >> 5) & 0x7) == 0x4) | ||
211 | dprintk("FE%d : MP005 : Single Sband", fe->id); | ||
212 | else if (((v >> 5) & 0x7) == 0x6) | ||
213 | dprintk("FE%d : MP008 : diversity VHF-UHF-LBAND", fe->id); | ||
214 | else if (((v >> 5) & 0x7) == 0x7) | ||
215 | dprintk("FE%d : MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND", fe->id); | ||
216 | else | ||
217 | return 0xff; | ||
218 | |||
219 | /* revision only */ | ||
220 | if ((v & 0x1f) == 0x3) | ||
221 | dprintk("FE%d : P1-D/E/F detected", fe->id); | ||
222 | else if ((v & 0x1f) == 0x1) | ||
223 | dprintk("FE%d : P1C detected", fe->id); | ||
224 | else if ((v & 0x1f) == 0x0) { | ||
225 | #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT | ||
226 | dprintk("FE%d : P1-A/B detected: using previous driver - support will be removed soon", fe->id); | ||
227 | dib0090_p1b_register(fe); | ||
228 | #else | ||
229 | dprintk("FE%d : P1-A/B detected: driver is deactivated - not available", fe->id); | ||
230 | return 0xff; | ||
231 | #endif | ||
232 | } | ||
233 | |||
234 | return v; | ||
235 | } | ||
236 | |||
237 | static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg) | ||
238 | { | ||
239 | struct dib0090_state *state = fe->tuner_priv; | ||
240 | |||
241 | HARD_RESET(state); | ||
242 | |||
243 | dib0090_write_reg(state, 0x24, EN_PLL); | ||
244 | dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */ | ||
245 | |||
246 | /* adcClkOutRatio=8->7, release reset */ | ||
247 | dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0); | ||
248 | if (cfg->clkoutdrive != 0) | ||
249 | dib0090_write_reg(state, 0x23, | ||
250 | (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (cfg->clkoutdrive << 5) | (cfg-> | ||
251 | clkouttobamse | ||
252 | << 4) | (0 | ||
253 | << | ||
254 | 2) | ||
255 | | (0)); | ||
256 | else | ||
257 | dib0090_write_reg(state, 0x23, | ||
258 | (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (7 << 5) | (cfg-> | ||
259 | clkouttobamse << 4) | (0 | ||
260 | << | ||
261 | 2) | ||
262 | | (0)); | ||
263 | |||
264 | /* enable pll, de-activate reset, ratio: 2/1 = 60MHz */ | ||
265 | dib0090_write_reg(state, 0x21, | ||
266 | (cfg->io.pll_bypass << 15) | (1 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)); | ||
267 | |||
268 | } | ||
269 | |||
270 | static int dib0090_wakeup(struct dvb_frontend *fe) | ||
271 | { | ||
272 | struct dib0090_state *state = fe->tuner_priv; | ||
273 | if (state->config->sleep) | ||
274 | state->config->sleep(fe, 0); | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int dib0090_sleep(struct dvb_frontend *fe) | ||
279 | { | ||
280 | struct dib0090_state *state = fe->tuner_priv; | ||
281 | if (state->config->sleep) | ||
282 | state->config->sleep(fe, 1); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) | ||
287 | { | ||
288 | struct dib0090_state *state = fe->tuner_priv; | ||
289 | if (fast) | ||
290 | dib0090_write_reg(state, 0x04, 0); | ||
291 | else | ||
292 | dib0090_write_reg(state, 0x04, 1); | ||
293 | } | ||
294 | EXPORT_SYMBOL(dib0090_dcc_freq); | ||
295 | |||
296 | static const u16 rf_ramp_pwm_cband[] = { | ||
297 | 0, /* max RF gain in 10th of dB */ | ||
298 | 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ | ||
299 | 0, /* ramp_max = maximum X used on the ramp */ | ||
300 | (0 << 10) | 0, /* 0x2c, LNA 1 = 0dB */ | ||
301 | (0 << 10) | 0, /* 0x2d, LNA 1 */ | ||
302 | (0 << 10) | 0, /* 0x2e, LNA 2 = 0dB */ | ||
303 | (0 << 10) | 0, /* 0x2f, LNA 2 */ | ||
304 | (0 << 10) | 0, /* 0x30, LNA 3 = 0dB */ | ||
305 | (0 << 10) | 0, /* 0x31, LNA 3 */ | ||
306 | (0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */ | ||
307 | (0 << 10) | 0, /* GAIN_4_2, LNA 4 */ | ||
308 | }; | ||
309 | |||
310 | static const u16 rf_ramp_vhf[] = { | ||
311 | 412, /* max RF gain in 10th of dB */ | ||
312 | 132, 307, 127, /* LNA1, 13.2dB */ | ||
313 | 105, 412, 255, /* LNA2, 10.5dB */ | ||
314 | 50, 50, 127, /* LNA3, 5dB */ | ||
315 | 125, 175, 127, /* LNA4, 12.5dB */ | ||
316 | 0, 0, 127, /* CBAND, 0dB */ | ||
317 | }; | ||
318 | |||
319 | static const u16 rf_ramp_uhf[] = { | ||
320 | 412, /* max RF gain in 10th of dB */ | ||
321 | 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 */ | ||
322 | 105, 412, 255, /* LNA2 : 10.5 dB */ | ||
323 | 50, 50, 127, /* LNA3 : 5.0 dB */ | ||
324 | 125, 175, 127, /* LNA4 : 12.5 dB */ | ||
325 | 0, 0, 127, /* CBAND : 0.0 dB */ | ||
326 | }; | ||
327 | |||
328 | static const u16 rf_ramp_cband[] = { | ||
329 | 332, /* max RF gain in 10th of dB */ | ||
330 | 132, 252, 127, /* LNA1, dB */ | ||
331 | 80, 332, 255, /* LNA2, dB */ | ||
332 | 0, 0, 127, /* LNA3, dB */ | ||
333 | 0, 0, 127, /* LNA4, dB */ | ||
334 | 120, 120, 127, /* LT1 CBAND */ | ||
335 | }; | ||
336 | |||
337 | static const u16 rf_ramp_pwm_vhf[] = { | ||
338 | 404, /* max RF gain in 10th of dB */ | ||
339 | 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ | ||
340 | 1011, /* ramp_max = maximum X used on the ramp */ | ||
341 | (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */ | ||
342 | (0 << 10) | 756, /* 0x2d, LNA 1 */ | ||
343 | (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */ | ||
344 | (0 << 10) | 1011, /* 0x2f, LNA 2 */ | ||
345 | (16 << 10) | 290, /* 0x30, LNA 3 = 5dB */ | ||
346 | (0 << 10) | 417, /* 0x31, LNA 3 */ | ||
347 | (7 << 10) | 0, /* GAIN_4_1, LNA 4 = 12.5dB */ | ||
348 | (0 << 10) | 290, /* GAIN_4_2, LNA 4 */ | ||
349 | }; | ||
350 | |||
351 | static const u16 rf_ramp_pwm_uhf[] = { | ||
352 | 404, /* max RF gain in 10th of dB */ | ||
353 | 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ | ||
354 | 1011, /* ramp_max = maximum X used on the ramp */ | ||
355 | (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */ | ||
356 | (0 << 10) | 756, /* 0x2d, LNA 1 */ | ||
357 | (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */ | ||
358 | (0 << 10) | 1011, /* 0x2f, LNA 2 */ | ||
359 | (16 << 10) | 0, /* 0x30, LNA 3 = 5dB */ | ||
360 | (0 << 10) | 127, /* 0x31, LNA 3 */ | ||
361 | (7 << 10) | 127, /* GAIN_4_1, LNA 4 = 12.5dB */ | ||
362 | (0 << 10) | 417, /* GAIN_4_2, LNA 4 */ | ||
363 | }; | ||
364 | |||
365 | static const u16 bb_ramp_boost[] = { | ||
366 | 550, /* max BB gain in 10th of dB */ | ||
367 | 260, 260, 26, /* BB1, 26dB */ | ||
368 | 290, 550, 29, /* BB2, 29dB */ | ||
369 | }; | ||
370 | |||
371 | static const u16 bb_ramp_pwm_normal[] = { | ||
372 | 500, /* max RF gain in 10th of dB */ | ||
373 | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */ | ||
374 | 400, | ||
375 | (2 << 9) | 0, /* 0x35 = 21dB */ | ||
376 | (0 << 9) | 168, /* 0x36 */ | ||
377 | (2 << 9) | 168, /* 0x37 = 29dB */ | ||
378 | (0 << 9) | 400, /* 0x38 */ | ||
379 | }; | ||
380 | |||
381 | struct slope { | ||
382 | int16_t range; | ||
383 | int16_t slope; | ||
384 | }; | ||
385 | static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val) | ||
386 | { | ||
387 | u8 i; | ||
388 | u16 rest; | ||
389 | u16 ret = 0; | ||
390 | for (i = 0; i < num; i++) { | ||
391 | if (val > slopes[i].range) | ||
392 | rest = slopes[i].range; | ||
393 | else | ||
394 | rest = val; | ||
395 | ret += (rest * slopes[i].slope) / slopes[i].range; | ||
396 | val -= rest; | ||
397 | } | ||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | static const struct slope dib0090_wbd_slopes[3] = { | ||
402 | {66, 120}, /* -64,-52: offset - 65 */ | ||
403 | {600, 170}, /* -52,-35: 65 - 665 */ | ||
404 | {170, 250}, /* -45,-10: 665 - 835 */ | ||
405 | }; | ||
406 | |||
407 | static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd) | ||
408 | { | ||
409 | wbd &= 0x3ff; | ||
410 | if (wbd < state->wbd_offset) | ||
411 | wbd = 0; | ||
412 | else | ||
413 | wbd -= state->wbd_offset; | ||
414 | /* -64dB is the floor */ | ||
415 | return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd); | ||
416 | } | ||
417 | |||
418 | static void dib0090_wbd_target(struct dib0090_state *state, u32 rf) | ||
419 | { | ||
420 | u16 offset = 250; | ||
421 | |||
422 | /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */ | ||
423 | |||
424 | if (state->current_band == BAND_VHF) | ||
425 | offset = 650; | ||
426 | #ifndef FIRMWARE_FIREFLY | ||
427 | if (state->current_band == BAND_VHF) | ||
428 | offset = state->config->wbd_vhf_offset; | ||
429 | if (state->current_band == BAND_CBAND) | ||
430 | offset = state->config->wbd_cband_offset; | ||
431 | #endif | ||
432 | |||
433 | state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset); | ||
434 | dprintk("wbd-target: %d dB", (u32) state->wbd_target); | ||
435 | } | ||
436 | |||
437 | static const int gain_reg_addr[4] = { | ||
438 | 0x08, 0x0a, 0x0f, 0x01 | ||
439 | }; | ||
440 | |||
441 | static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force) | ||
442 | { | ||
443 | u16 rf, bb, ref; | ||
444 | u16 i, v, gain_reg[4] = { 0 }, gain; | ||
445 | const u16 *g; | ||
446 | |||
447 | if (top_delta < -511) | ||
448 | top_delta = -511; | ||
449 | if (top_delta > 511) | ||
450 | top_delta = 511; | ||
451 | |||
452 | if (force) { | ||
453 | top_delta *= (1 << WBD_ALPHA); | ||
454 | gain_delta *= (1 << GAIN_ALPHA); | ||
455 | } | ||
456 | |||
457 | if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit)) /* overflow */ | ||
458 | state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA; | ||
459 | else | ||
460 | state->rf_gain_limit += top_delta; | ||
461 | |||
462 | if (state->rf_gain_limit < 0) /*underflow */ | ||
463 | state->rf_gain_limit = 0; | ||
464 | |||
465 | /* use gain as a temporary variable and correct current_gain */ | ||
466 | gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA; | ||
467 | if (gain_delta >= ((s16) gain - state->current_gain)) /* overflow */ | ||
468 | state->current_gain = gain; | ||
469 | else | ||
470 | state->current_gain += gain_delta; | ||
471 | /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */ | ||
472 | if (state->current_gain < 0) | ||
473 | state->current_gain = 0; | ||
474 | |||
475 | /* now split total gain to rf and bb gain */ | ||
476 | gain = state->current_gain >> GAIN_ALPHA; | ||
477 | |||
478 | /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */ | ||
479 | if (gain > (state->rf_gain_limit >> WBD_ALPHA)) { | ||
480 | rf = state->rf_gain_limit >> WBD_ALPHA; | ||
481 | bb = gain - rf; | ||
482 | if (bb > state->bb_ramp[0]) | ||
483 | bb = state->bb_ramp[0]; | ||
484 | } else { /* high signal level -> all gains put on RF */ | ||
485 | rf = gain; | ||
486 | bb = 0; | ||
487 | } | ||
488 | |||
489 | state->gain[0] = rf; | ||
490 | state->gain[1] = bb; | ||
491 | |||
492 | /* software ramp */ | ||
493 | /* Start with RF gains */ | ||
494 | g = state->rf_ramp + 1; /* point on RF LNA1 max gain */ | ||
495 | ref = rf; | ||
496 | for (i = 0; i < 7; i++) { /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */ | ||
497 | 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 */ | ||
498 | v = 0; /* force the gain to write for the current amp to be null */ | ||
499 | else if (ref >= g[1]) /* Gain to set is higher than the high working point of this amp */ | ||
500 | v = g[2]; /* force this amp to be full gain */ | ||
501 | else /* compute the value to set to this amp because we are somewhere in his range */ | ||
502 | v = ((ref - (g[1] - g[0])) * g[2]) / g[0]; | ||
503 | |||
504 | if (i == 0) /* LNA 1 reg mapping */ | ||
505 | gain_reg[0] = v; | ||
506 | else if (i == 1) /* LNA 2 reg mapping */ | ||
507 | gain_reg[0] |= v << 7; | ||
508 | else if (i == 2) /* LNA 3 reg mapping */ | ||
509 | gain_reg[1] = v; | ||
510 | else if (i == 3) /* LNA 4 reg mapping */ | ||
511 | gain_reg[1] |= v << 7; | ||
512 | else if (i == 4) /* CBAND LNA reg mapping */ | ||
513 | gain_reg[2] = v | state->rf_lt_def; | ||
514 | else if (i == 5) /* BB gain 1 reg mapping */ | ||
515 | gain_reg[3] = v << 3; | ||
516 | else if (i == 6) /* BB gain 2 reg mapping */ | ||
517 | gain_reg[3] |= v << 8; | ||
518 | |||
519 | g += 3; /* go to next gain bloc */ | ||
520 | |||
521 | /* When RF is finished, start with BB */ | ||
522 | if (i == 4) { | ||
523 | g = state->bb_ramp + 1; /* point on BB gain 1 max gain */ | ||
524 | ref = bb; | ||
525 | } | ||
526 | } | ||
527 | gain_reg[3] |= state->bb_1_def; | ||
528 | gain_reg[3] |= ((bb % 10) * 100) / 125; | ||
529 | |||
530 | #ifdef DEBUG_AGC | ||
531 | 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, | ||
532 | gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]); | ||
533 | #endif | ||
534 | |||
535 | /* Write the amplifier regs */ | ||
536 | for (i = 0; i < 4; i++) { | ||
537 | v = gain_reg[i]; | ||
538 | if (force || state->gain_reg[i] != v) { | ||
539 | state->gain_reg[i] = v; | ||
540 | dib0090_write_reg(state, gain_reg_addr[i], v); | ||
541 | } | ||
542 | } | ||
543 | } | ||
544 | |||
545 | static void dib0090_set_boost(struct dib0090_state *state, int onoff) | ||
546 | { | ||
547 | state->bb_1_def &= 0xdfff; | ||
548 | state->bb_1_def |= onoff << 13; | ||
549 | } | ||
550 | |||
551 | static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg) | ||
552 | { | ||
553 | state->rf_ramp = cfg; | ||
554 | } | ||
555 | |||
556 | static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg) | ||
557 | { | ||
558 | state->rf_ramp = cfg; | ||
559 | |||
560 | dib0090_write_reg(state, 0x2a, 0xffff); | ||
561 | |||
562 | dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a)); | ||
563 | |||
564 | dib0090_write_regs(state, 0x2c, cfg + 3, 6); | ||
565 | dib0090_write_regs(state, 0x3e, cfg + 9, 2); | ||
566 | } | ||
567 | |||
568 | static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg) | ||
569 | { | ||
570 | state->bb_ramp = cfg; | ||
571 | dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */ | ||
572 | } | ||
573 | |||
574 | static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg) | ||
575 | { | ||
576 | state->bb_ramp = cfg; | ||
577 | |||
578 | dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */ | ||
579 | |||
580 | dib0090_write_reg(state, 0x33, 0xffff); | ||
581 | dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33)); | ||
582 | dib0090_write_regs(state, 0x35, cfg + 3, 4); | ||
583 | } | ||
584 | |||
585 | void dib0090_pwm_gain_reset(struct dvb_frontend *fe) | ||
586 | { | ||
587 | struct dib0090_state *state = fe->tuner_priv; | ||
588 | /* reset the AGC */ | ||
589 | |||
590 | if (state->config->use_pwm_agc) { | ||
591 | #ifdef CONFIG_BAND_SBAND | ||
592 | if (state->current_band == BAND_SBAND) { | ||
593 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband); | ||
594 | dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost); | ||
595 | } else | ||
596 | #endif | ||
597 | #ifdef CONFIG_BAND_CBAND | ||
598 | if (state->current_band == BAND_CBAND) { | ||
599 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband); | ||
600 | dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); | ||
601 | } else | ||
602 | #endif | ||
603 | #ifdef CONFIG_BAND_VHF | ||
604 | if (state->current_band == BAND_VHF) { | ||
605 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf); | ||
606 | dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); | ||
607 | } else | ||
608 | #endif | ||
609 | { | ||
610 | dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf); | ||
611 | dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); | ||
612 | } | ||
613 | |||
614 | if (state->rf_ramp[0] != 0) | ||
615 | dib0090_write_reg(state, 0x32, (3 << 11)); | ||
616 | else | ||
617 | dib0090_write_reg(state, 0x32, (0 << 11)); | ||
618 | |||
619 | dib0090_write_reg(state, 0x39, (1 << 10)); | ||
620 | } | ||
621 | } | ||
622 | EXPORT_SYMBOL(dib0090_pwm_gain_reset); | ||
623 | |||
624 | int dib0090_gain_control(struct dvb_frontend *fe) | ||
625 | { | ||
626 | struct dib0090_state *state = fe->tuner_priv; | ||
627 | enum frontend_tune_state *tune_state = &state->tune_state; | ||
628 | int ret = 10; | ||
629 | |||
630 | u16 wbd_val = 0; | ||
631 | u8 apply_gain_immediatly = 1; | ||
632 | s16 wbd_error = 0, adc_error = 0; | ||
633 | |||
634 | if (*tune_state == CT_AGC_START) { | ||
635 | state->agc_freeze = 0; | ||
636 | dib0090_write_reg(state, 0x04, 0x0); | ||
637 | |||
638 | #ifdef CONFIG_BAND_SBAND | ||
639 | if (state->current_band == BAND_SBAND) { | ||
640 | dib0090_set_rframp(state, rf_ramp_sband); | ||
641 | dib0090_set_bbramp(state, bb_ramp_boost); | ||
642 | } else | ||
643 | #endif | ||
644 | #ifdef CONFIG_BAND_VHF | ||
645 | if (state->current_band == BAND_VHF) { | ||
646 | dib0090_set_rframp(state, rf_ramp_vhf); | ||
647 | dib0090_set_bbramp(state, bb_ramp_boost); | ||
648 | } else | ||
649 | #endif | ||
650 | #ifdef CONFIG_BAND_CBAND | ||
651 | if (state->current_band == BAND_CBAND) { | ||
652 | dib0090_set_rframp(state, rf_ramp_cband); | ||
653 | dib0090_set_bbramp(state, bb_ramp_boost); | ||
654 | } else | ||
655 | #endif | ||
656 | { | ||
657 | dib0090_set_rframp(state, rf_ramp_uhf); | ||
658 | dib0090_set_bbramp(state, bb_ramp_boost); | ||
659 | } | ||
660 | |||
661 | dib0090_write_reg(state, 0x32, 0); | ||
662 | dib0090_write_reg(state, 0x39, 0); | ||
663 | |||
664 | dib0090_wbd_target(state, state->current_rf); | ||
665 | |||
666 | state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA; | ||
667 | state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA; | ||
668 | |||
669 | *tune_state = CT_AGC_STEP_0; | ||
670 | } else if (!state->agc_freeze) { | ||
671 | s16 wbd; | ||
672 | |||
673 | int adc; | ||
674 | wbd_val = dib0090_read_reg(state, 0x1d); | ||
675 | |||
676 | /* read and calc the wbd power */ | ||
677 | wbd = dib0090_wbd_to_db(state, wbd_val); | ||
678 | wbd_error = state->wbd_target - wbd; | ||
679 | |||
680 | if (*tune_state == CT_AGC_STEP_0) { | ||
681 | if (wbd_error < 0 && state->rf_gain_limit > 0) { | ||
682 | #ifdef CONFIG_BAND_CBAND | ||
683 | /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */ | ||
684 | u8 ltg2 = (state->rf_lt_def >> 10) & 0x7; | ||
685 | if (state->current_band == BAND_CBAND && ltg2) { | ||
686 | ltg2 >>= 1; | ||
687 | state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */ | ||
688 | } | ||
689 | #endif | ||
690 | } else { | ||
691 | state->agc_step = 0; | ||
692 | *tune_state = CT_AGC_STEP_1; | ||
693 | } | ||
694 | } else { | ||
695 | /* calc the adc power */ | ||
696 | adc = state->config->get_adc_power(fe); | ||
697 | adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */ | ||
698 | |||
699 | adc_error = (s16) (((s32) ADC_TARGET) - adc); | ||
700 | #ifdef CONFIG_STANDARD_DAB | ||
701 | if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) | ||
702 | adc_error += 130; | ||
703 | #endif | ||
704 | #ifdef CONFIG_STANDARD_DVBT | ||
705 | if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT && | ||
706 | (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16)) | ||
707 | adc_error += 60; | ||
708 | #endif | ||
709 | #ifdef CONFIG_SYS_ISDBT | ||
710 | if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count > | ||
711 | 0) | ||
712 | && | ||
713 | ((state->fe->dtv_property_cache.layer[0].modulation == | ||
714 | QAM_64) | ||
715 | || (state->fe->dtv_property_cache.layer[0]. | ||
716 | modulation == QAM_16))) | ||
717 | || | ||
718 | ((state->fe->dtv_property_cache.layer[1].segment_count > | ||
719 | 0) | ||
720 | && | ||
721 | ((state->fe->dtv_property_cache.layer[1].modulation == | ||
722 | QAM_64) | ||
723 | || (state->fe->dtv_property_cache.layer[1]. | ||
724 | modulation == QAM_16))) | ||
725 | || | ||
726 | ((state->fe->dtv_property_cache.layer[2].segment_count > | ||
727 | 0) | ||
728 | && | ||
729 | ((state->fe->dtv_property_cache.layer[2].modulation == | ||
730 | QAM_64) | ||
731 | || (state->fe->dtv_property_cache.layer[2]. | ||
732 | modulation == QAM_16))) | ||
733 | ) | ||
734 | ) | ||
735 | adc_error += 60; | ||
736 | #endif | ||
737 | |||
738 | if (*tune_state == CT_AGC_STEP_1) { /* quickly go to the correct range of the ADC power */ | ||
739 | if (ABS(adc_error) < 50 || state->agc_step++ > 5) { | ||
740 | |||
741 | #ifdef CONFIG_STANDARD_DAB | ||
742 | if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) { | ||
743 | dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63)); /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */ | ||
744 | dib0090_write_reg(state, 0x04, 0x0); | ||
745 | } else | ||
746 | #endif | ||
747 | { | ||
748 | dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32)); | ||
749 | dib0090_write_reg(state, 0x04, 0x01); /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */ | ||
750 | } | ||
751 | |||
752 | *tune_state = CT_AGC_STOP; | ||
753 | } | ||
754 | } else { | ||
755 | /* everything higher than or equal to CT_AGC_STOP means tracking */ | ||
756 | ret = 100; /* 10ms interval */ | ||
757 | apply_gain_immediatly = 0; | ||
758 | } | ||
759 | } | ||
760 | #ifdef DEBUG_AGC | ||
761 | dprintk | ||
762 | ("FE: %d, tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm", | ||
763 | (u32) fe->id, (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, | ||
764 | (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA)); | ||
765 | #endif | ||
766 | } | ||
767 | |||
768 | /* apply gain */ | ||
769 | if (!state->agc_freeze) | ||
770 | dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly); | ||
771 | return ret; | ||
772 | } | ||
773 | EXPORT_SYMBOL(dib0090_gain_control); | ||
774 | |||
775 | void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) | ||
776 | { | ||
777 | struct dib0090_state *state = fe->tuner_priv; | ||
778 | if (rf) | ||
779 | *rf = state->gain[0]; | ||
780 | if (bb) | ||
781 | *bb = state->gain[1]; | ||
782 | if (rf_gain_limit) | ||
783 | *rf_gain_limit = state->rf_gain_limit; | ||
784 | if (rflt) | ||
785 | *rflt = (state->rf_lt_def >> 10) & 0x7; | ||
786 | } | ||
787 | EXPORT_SYMBOL(dib0090_get_current_gain); | ||
788 | |||
789 | u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) | ||
790 | { | ||
791 | struct dib0090_state *st = tuner->tuner_priv; | ||
792 | return st->wbd_offset; | ||
793 | } | ||
794 | EXPORT_SYMBOL(dib0090_get_wbd_offset); | ||
795 | |||
796 | static const u16 dib0090_defaults[] = { | ||
797 | |||
798 | 25, 0x01, | ||
799 | 0x0000, | ||
800 | 0x99a0, | ||
801 | 0x6008, | ||
802 | 0x0000, | ||
803 | 0x8acb, | ||
804 | 0x0000, | ||
805 | 0x0405, | ||
806 | 0x0000, | ||
807 | 0x0000, | ||
808 | 0x0000, | ||
809 | 0xb802, | ||
810 | 0x0300, | ||
811 | 0x2d12, | ||
812 | 0xbac0, | ||
813 | 0x7c00, | ||
814 | 0xdbb9, | ||
815 | 0x0954, | ||
816 | 0x0743, | ||
817 | 0x8000, | ||
818 | 0x0001, | ||
819 | 0x0040, | ||
820 | 0x0100, | ||
821 | 0x0000, | ||
822 | 0xe910, | ||
823 | 0x149e, | ||
824 | |||
825 | 1, 0x1c, | ||
826 | 0xff2d, | ||
827 | |||
828 | 1, 0x39, | ||
829 | 0x0000, | ||
830 | |||
831 | 1, 0x1b, | ||
832 | EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL, | ||
833 | 2, 0x1e, | ||
834 | 0x07FF, | ||
835 | 0x0007, | ||
836 | |||
837 | 1, 0x24, | ||
838 | EN_UHF | EN_CRYSTAL, | ||
839 | |||
840 | 2, 0x3c, | ||
841 | 0x3ff, | ||
842 | 0x111, | ||
843 | 0 | ||
844 | }; | ||
845 | |||
846 | static int dib0090_reset(struct dvb_frontend *fe) | ||
847 | { | ||
848 | struct dib0090_state *state = fe->tuner_priv; | ||
849 | u16 l, r, *n; | ||
850 | |||
851 | dib0090_reset_digital(fe, state->config); | ||
852 | state->revision = dib0090_identify(fe); | ||
853 | |||
854 | /* Revision definition */ | ||
855 | if (state->revision == 0xff) | ||
856 | return -EINVAL; | ||
857 | #ifdef EFUSE | ||
858 | else if ((state->revision & 0x1f) >= 3) /* Update the efuse : Only available for KROSUS > P1C */ | ||
859 | dib0090_set_EFUSE(state); | ||
860 | #endif | ||
861 | |||
862 | #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT | ||
863 | if (!(state->revision & 0x1)) /* it is P1B - reset is already done */ | ||
864 | return 0; | ||
865 | #endif | ||
866 | |||
867 | /* Upload the default values */ | ||
868 | n = (u16 *) dib0090_defaults; | ||
869 | l = pgm_read_word(n++); | ||
870 | while (l) { | ||
871 | r = pgm_read_word(n++); | ||
872 | do { | ||
873 | /* DEBUG_TUNER */ | ||
874 | /* dprintk("%d, %d, %d", l, r, pgm_read_word(n)); */ | ||
875 | dib0090_write_reg(state, r, pgm_read_word(n++)); | ||
876 | r++; | ||
877 | } while (--l); | ||
878 | l = pgm_read_word(n++); | ||
879 | } | ||
880 | |||
881 | /* Congigure in function of the crystal */ | ||
882 | if (state->config->io.clock_khz >= 24000) | ||
883 | l = 1; | ||
884 | else | ||
885 | l = 2; | ||
886 | dib0090_write_reg(state, 0x14, l); | ||
887 | dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1); | ||
888 | |||
889 | state->reset = 3; /* enable iq-offset-calibration and wbd-calibration when tuning next time */ | ||
890 | |||
891 | return 0; | ||
892 | } | ||
893 | |||
894 | #define steps(u) (((u) > 15) ? ((u)-16) : (u)) | ||
895 | #define INTERN_WAIT 10 | ||
896 | static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state) | ||
897 | { | ||
898 | int ret = INTERN_WAIT * 10; | ||
899 | |||
900 | switch (*tune_state) { | ||
901 | case CT_TUNER_STEP_2: | ||
902 | /* Turns to positive */ | ||
903 | dib0090_write_reg(state, 0x1f, 0x7); | ||
904 | *tune_state = CT_TUNER_STEP_3; | ||
905 | break; | ||
906 | |||
907 | case CT_TUNER_STEP_3: | ||
908 | state->adc_diff = dib0090_read_reg(state, 0x1d); | ||
909 | |||
910 | /* Turns to negative */ | ||
911 | dib0090_write_reg(state, 0x1f, 0x4); | ||
912 | *tune_state = CT_TUNER_STEP_4; | ||
913 | break; | ||
914 | |||
915 | case CT_TUNER_STEP_4: | ||
916 | state->adc_diff -= dib0090_read_reg(state, 0x1d); | ||
917 | *tune_state = CT_TUNER_STEP_5; | ||
918 | ret = 0; | ||
919 | break; | ||
920 | |||
921 | default: | ||
922 | break; | ||
923 | } | ||
924 | |||
925 | return ret; | ||
926 | } | ||
927 | |||
928 | struct dc_calibration { | ||
929 | uint8_t addr; | ||
930 | uint8_t offset; | ||
931 | uint8_t pga:1; | ||
932 | uint16_t bb1; | ||
933 | uint8_t i:1; | ||
934 | }; | ||
935 | |||
936 | static const struct dc_calibration dc_table[] = { | ||
937 | /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */ | ||
938 | {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1}, | ||
939 | {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0}, | ||
940 | /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */ | ||
941 | {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1}, | ||
942 | {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0}, | ||
943 | {0}, | ||
944 | }; | ||
945 | |||
946 | static void dib0090_set_trim(struct dib0090_state *state) | ||
947 | { | ||
948 | u16 *val; | ||
949 | |||
950 | if (state->dc->addr == 0x07) | ||
951 | val = &state->bb7; | ||
952 | else | ||
953 | val = &state->bb6; | ||
954 | |||
955 | *val &= ~(0x1f << state->dc->offset); | ||
956 | *val |= state->step << state->dc->offset; | ||
957 | |||
958 | dib0090_write_reg(state, state->dc->addr, *val); | ||
959 | } | ||
960 | |||
961 | static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) | ||
962 | { | ||
963 | int ret = 0; | ||
964 | |||
965 | switch (*tune_state) { | ||
966 | |||
967 | case CT_TUNER_START: | ||
968 | /* init */ | ||
969 | dprintk("Internal DC calibration"); | ||
970 | |||
971 | /* the LNA is off */ | ||
972 | dib0090_write_reg(state, 0x24, 0x02ed); | ||
973 | |||
974 | /* force vcm2 = 0.8V */ | ||
975 | state->bb6 = 0; | ||
976 | state->bb7 = 0x040d; | ||
977 | |||
978 | state->dc = dc_table; | ||
979 | |||
980 | *tune_state = CT_TUNER_STEP_0; | ||
981 | |||
982 | /* fall through */ | ||
983 | |||
984 | case CT_TUNER_STEP_0: | ||
985 | dib0090_write_reg(state, 0x01, state->dc->bb1); | ||
986 | dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7)); | ||
987 | |||
988 | state->step = 0; | ||
989 | |||
990 | state->min_adc_diff = 1023; | ||
991 | |||
992 | *tune_state = CT_TUNER_STEP_1; | ||
993 | ret = 50; | ||
994 | break; | ||
995 | |||
996 | case CT_TUNER_STEP_1: | ||
997 | dib0090_set_trim(state); | ||
998 | |||
999 | *tune_state = CT_TUNER_STEP_2; | ||
1000 | break; | ||
1001 | |||
1002 | case CT_TUNER_STEP_2: | ||
1003 | case CT_TUNER_STEP_3: | ||
1004 | case CT_TUNER_STEP_4: | ||
1005 | ret = dib0090_get_offset(state, tune_state); | ||
1006 | break; | ||
1007 | |||
1008 | case CT_TUNER_STEP_5: /* found an offset */ | ||
1009 | dprintk("FE%d: IQC read=%d, current=%x", state->fe->id, (u32) state->adc_diff, state->step); | ||
1010 | |||
1011 | /* first turn for this frequency */ | ||
1012 | if (state->step == 0) { | ||
1013 | if (state->dc->pga && state->adc_diff < 0) | ||
1014 | state->step = 0x10; | ||
1015 | if (state->dc->pga == 0 && state->adc_diff > 0) | ||
1016 | state->step = 0x10; | ||
1017 | } | ||
1018 | |||
1019 | state->adc_diff = ABS(state->adc_diff); | ||
1020 | |||
1021 | if (state->adc_diff < state->min_adc_diff && steps(state->step) < 15) { /* stop search when the delta to 0 is increasing */ | ||
1022 | state->step++; | ||
1023 | state->min_adc_diff = state->adc_diff; | ||
1024 | *tune_state = CT_TUNER_STEP_1; | ||
1025 | } else { | ||
1026 | |||
1027 | /* the minimum was what we have seen in the step before */ | ||
1028 | state->step--; | ||
1029 | dib0090_set_trim(state); | ||
1030 | |||
1031 | dprintk("FE%d: BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->fe->id, state->dc->addr, state->adc_diff, | ||
1032 | state->step); | ||
1033 | |||
1034 | state->dc++; | ||
1035 | if (state->dc->addr == 0) /* done */ | ||
1036 | *tune_state = CT_TUNER_STEP_6; | ||
1037 | else | ||
1038 | *tune_state = CT_TUNER_STEP_0; | ||
1039 | |||
1040 | } | ||
1041 | break; | ||
1042 | |||
1043 | case CT_TUNER_STEP_6: | ||
1044 | dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008); | ||
1045 | dib0090_write_reg(state, 0x1f, 0x7); | ||
1046 | *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ | ||
1047 | state->reset &= ~0x1; | ||
1048 | default: | ||
1049 | break; | ||
1050 | } | ||
1051 | return ret; | ||
1052 | } | ||
1053 | |||
1054 | static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) | ||
1055 | { | ||
1056 | switch (*tune_state) { | ||
1057 | case CT_TUNER_START: | ||
1058 | /* WBD-mode=log, Bias=2, Gain=6, Testmode=1, en=1, WBDMUX=1 */ | ||
1059 | dib0090_write_reg(state, 0x10, 0xdb09 | (1 << 10)); | ||
1060 | dib0090_write_reg(state, 0x24, EN_UHF & 0x0fff); | ||
1061 | |||
1062 | *tune_state = CT_TUNER_STEP_0; | ||
1063 | return 90; /* wait for the WBDMUX to switch and for the ADC to sample */ | ||
1064 | case CT_TUNER_STEP_0: | ||
1065 | state->wbd_offset = dib0090_read_reg(state, 0x1d); | ||
1066 | dprintk("WBD calibration offset = %d", state->wbd_offset); | ||
1067 | |||
1068 | *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ | ||
1069 | state->reset &= ~0x2; | ||
1070 | break; | ||
1071 | default: | ||
1072 | break; | ||
1073 | } | ||
1074 | return 0; | ||
1075 | } | ||
1076 | |||
1077 | static void dib0090_set_bandwidth(struct dib0090_state *state) | ||
1078 | { | ||
1079 | u16 tmp; | ||
1080 | |||
1081 | if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000) | ||
1082 | tmp = (3 << 14); | ||
1083 | else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000) | ||
1084 | tmp = (2 << 14); | ||
1085 | else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000) | ||
1086 | tmp = (1 << 14); | ||
1087 | else | ||
1088 | tmp = (0 << 14); | ||
1089 | |||
1090 | state->bb_1_def &= 0x3fff; | ||
1091 | state->bb_1_def |= tmp; | ||
1092 | |||
1093 | dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */ | ||
1094 | } | ||
1095 | |||
1096 | static const struct dib0090_pll dib0090_pll_table[] = { | ||
1097 | #ifdef CONFIG_BAND_CBAND | ||
1098 | {56000, 0, 9, 48, 6}, | ||
1099 | {70000, 1, 9, 48, 6}, | ||
1100 | {87000, 0, 8, 32, 4}, | ||
1101 | {105000, 1, 8, 32, 4}, | ||
1102 | {115000, 0, 7, 24, 6}, | ||
1103 | {140000, 1, 7, 24, 6}, | ||
1104 | {170000, 0, 6, 16, 4}, | ||
1105 | #endif | ||
1106 | #ifdef CONFIG_BAND_VHF | ||
1107 | {200000, 1, 6, 16, 4}, | ||
1108 | {230000, 0, 5, 12, 6}, | ||
1109 | {280000, 1, 5, 12, 6}, | ||
1110 | {340000, 0, 4, 8, 4}, | ||
1111 | {380000, 1, 4, 8, 4}, | ||
1112 | {450000, 0, 3, 6, 6}, | ||
1113 | #endif | ||
1114 | #ifdef CONFIG_BAND_UHF | ||
1115 | {580000, 1, 3, 6, 6}, | ||
1116 | {700000, 0, 2, 4, 4}, | ||
1117 | {860000, 1, 2, 4, 4}, | ||
1118 | #endif | ||
1119 | #ifdef CONFIG_BAND_LBAND | ||
1120 | {1800000, 1, 0, 2, 4}, | ||
1121 | #endif | ||
1122 | #ifdef CONFIG_BAND_SBAND | ||
1123 | {2900000, 0, 14, 1, 4}, | ||
1124 | #endif | ||
1125 | }; | ||
1126 | |||
1127 | static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = { | ||
1128 | |||
1129 | #ifdef CONFIG_BAND_CBAND | ||
1130 | {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, | ||
1131 | {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, | ||
1132 | {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, | ||
1133 | #endif | ||
1134 | #ifdef CONFIG_BAND_UHF | ||
1135 | {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1136 | {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1137 | {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1138 | {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1139 | {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1140 | {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1141 | #endif | ||
1142 | #ifdef CONFIG_BAND_LBAND | ||
1143 | {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, | ||
1144 | {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, | ||
1145 | {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, | ||
1146 | #endif | ||
1147 | #ifdef CONFIG_BAND_SBAND | ||
1148 | {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, | ||
1149 | {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, | ||
1150 | #endif | ||
1151 | }; | ||
1152 | |||
1153 | static const struct dib0090_tuning dib0090_tuning_table[] = { | ||
1154 | |||
1155 | #ifdef CONFIG_BAND_CBAND | ||
1156 | {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB}, | ||
1157 | #endif | ||
1158 | #ifdef CONFIG_BAND_VHF | ||
1159 | {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, | ||
1160 | {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, | ||
1161 | {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF}, | ||
1162 | #endif | ||
1163 | #ifdef CONFIG_BAND_UHF | ||
1164 | {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1165 | {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1166 | {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1167 | {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1168 | {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1169 | {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF}, | ||
1170 | #endif | ||
1171 | #ifdef CONFIG_BAND_LBAND | ||
1172 | {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, | ||
1173 | {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, | ||
1174 | {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD}, | ||
1175 | #endif | ||
1176 | #ifdef CONFIG_BAND_SBAND | ||
1177 | {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD}, | ||
1178 | {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD}, | ||
1179 | #endif | ||
1180 | }; | ||
1181 | |||
1182 | #define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */ | ||
1183 | static int dib0090_tune(struct dvb_frontend *fe) | ||
1184 | { | ||
1185 | struct dib0090_state *state = fe->tuner_priv; | ||
1186 | const struct dib0090_tuning *tune = state->current_tune_table_index; | ||
1187 | const struct dib0090_pll *pll = state->current_pll_table_index; | ||
1188 | enum frontend_tune_state *tune_state = &state->tune_state; | ||
1189 | |||
1190 | u32 rf; | ||
1191 | u16 lo4 = 0xe900, lo5, lo6, Den; | ||
1192 | u32 FBDiv, Rest, FREF, VCOF_kHz = 0; | ||
1193 | u16 tmp, adc; | ||
1194 | int8_t step_sign; | ||
1195 | int ret = 10; /* 1ms is the default delay most of the time */ | ||
1196 | u8 c, i; | ||
1197 | |||
1198 | state->current_band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000); | ||
1199 | rf = fe->dtv_property_cache.frequency / 1000 + (state->current_band == | ||
1200 | BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->freq_offset_khz_vhf); | ||
1201 | /* in any case we first need to do a reset if needed */ | ||
1202 | if (state->reset & 0x1) | ||
1203 | return dib0090_dc_offset_calibration(state, tune_state); | ||
1204 | else if (state->reset & 0x2) | ||
1205 | return dib0090_wbd_calibration(state, tune_state); | ||
1206 | |||
1207 | /************************* VCO ***************************/ | ||
1208 | /* Default values for FG */ | ||
1209 | /* from these are needed : */ | ||
1210 | /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */ | ||
1211 | |||
1212 | #ifdef CONFIG_SYS_ISDBT | ||
1213 | if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) | ||
1214 | rf += 850; | ||
1215 | #endif | ||
1216 | |||
1217 | if (state->current_rf != rf) { | ||
1218 | state->tuner_is_tuned = 0; | ||
1219 | |||
1220 | tune = dib0090_tuning_table; | ||
1221 | |||
1222 | tmp = (state->revision >> 5) & 0x7; | ||
1223 | if (tmp == 0x4 || tmp == 0x7) { | ||
1224 | /* CBAND tuner version for VHF */ | ||
1225 | if (state->current_band == BAND_FM || state->current_band == BAND_VHF) { | ||
1226 | /* Force CBAND */ | ||
1227 | state->current_band = BAND_CBAND; | ||
1228 | tune = dib0090_tuning_table_fm_vhf_on_cband; | ||
1229 | } | ||
1230 | } | ||
1231 | |||
1232 | pll = dib0090_pll_table; | ||
1233 | /* Look for the interval */ | ||
1234 | while (rf > tune->max_freq) | ||
1235 | tune++; | ||
1236 | while (rf > pll->max_freq) | ||
1237 | pll++; | ||
1238 | state->current_tune_table_index = tune; | ||
1239 | state->current_pll_table_index = pll; | ||
1240 | } | ||
1241 | |||
1242 | if (*tune_state == CT_TUNER_START) { | ||
1243 | |||
1244 | if (state->tuner_is_tuned == 0) | ||
1245 | state->current_rf = 0; | ||
1246 | |||
1247 | if (state->current_rf != rf) { | ||
1248 | |||
1249 | dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim)); | ||
1250 | |||
1251 | /* external loop filter, otherwise: | ||
1252 | * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4; | ||
1253 | * lo6 = 0x0e34 */ | ||
1254 | if (pll->vco_band) | ||
1255 | lo5 = 0x049e; | ||
1256 | else if (state->config->analog_output) | ||
1257 | lo5 = 0x041d; | ||
1258 | else | ||
1259 | lo5 = 0x041c; | ||
1260 | |||
1261 | lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */ | ||
1262 | |||
1263 | if (!state->config->io.pll_int_loop_filt) | ||
1264 | lo6 = 0xff28; | ||
1265 | else | ||
1266 | lo6 = (state->config->io.pll_int_loop_filt << 3); | ||
1267 | |||
1268 | VCOF_kHz = (pll->hfdiv * rf) * 2; | ||
1269 | |||
1270 | FREF = state->config->io.clock_khz; | ||
1271 | |||
1272 | FBDiv = (VCOF_kHz / pll->topresc / FREF); | ||
1273 | Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF; | ||
1274 | |||
1275 | if (Rest < LPF) | ||
1276 | Rest = 0; | ||
1277 | else if (Rest < 2 * LPF) | ||
1278 | Rest = 2 * LPF; | ||
1279 | else if (Rest > (FREF - LPF)) { | ||
1280 | Rest = 0; | ||
1281 | FBDiv += 1; | ||
1282 | } else if (Rest > (FREF - 2 * LPF)) | ||
1283 | Rest = FREF - 2 * LPF; | ||
1284 | Rest = (Rest * 6528) / (FREF / 10); | ||
1285 | |||
1286 | Den = 1; | ||
1287 | |||
1288 | dprintk(" ***** ******* Rest value = %d", Rest); | ||
1289 | |||
1290 | if (Rest > 0) { | ||
1291 | if (state->config->analog_output) | ||
1292 | lo6 |= (1 << 2) | 2; | ||
1293 | else | ||
1294 | lo6 |= (1 << 2) | 1; | ||
1295 | Den = 255; | ||
1296 | } | ||
1297 | #ifdef CONFIG_BAND_SBAND | ||
1298 | if (state->current_band == BAND_SBAND) | ||
1299 | lo6 &= 0xfffb; | ||
1300 | #endif | ||
1301 | |||
1302 | dib0090_write_reg(state, 0x15, (u16) FBDiv); | ||
1303 | |||
1304 | dib0090_write_reg(state, 0x16, (Den << 8) | 1); | ||
1305 | |||
1306 | dib0090_write_reg(state, 0x17, (u16) Rest); | ||
1307 | |||
1308 | dib0090_write_reg(state, 0x19, lo5); | ||
1309 | |||
1310 | dib0090_write_reg(state, 0x1c, lo6); | ||
1311 | |||
1312 | lo6 = tune->tuner_enable; | ||
1313 | if (state->config->analog_output) | ||
1314 | lo6 = (lo6 & 0xff9f) | 0x2; | ||
1315 | |||
1316 | dib0090_write_reg(state, 0x24, lo6 | EN_LO | ||
1317 | #ifdef CONFIG_DIB0090_USE_PWM_AGC | ||
1318 | | state->config->use_pwm_agc * EN_CRYSTAL | ||
1319 | #endif | ||
1320 | ); | ||
1321 | |||
1322 | state->current_rf = rf; | ||
1323 | |||
1324 | /* prepare a complete captrim */ | ||
1325 | state->step = state->captrim = state->fcaptrim = 64; | ||
1326 | |||
1327 | } else { /* we are already tuned to this frequency - the configuration is correct */ | ||
1328 | |||
1329 | /* do a minimal captrim even if the frequency has not changed */ | ||
1330 | state->step = 4; | ||
1331 | state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f; | ||
1332 | } | ||
1333 | state->adc_diff = 3000; | ||
1334 | |||
1335 | dib0090_write_reg(state, 0x10, 0x2B1); | ||
1336 | |||
1337 | dib0090_write_reg(state, 0x1e, 0x0032); | ||
1338 | |||
1339 | ret = 20; | ||
1340 | *tune_state = CT_TUNER_STEP_1; | ||
1341 | } else if (*tune_state == CT_TUNER_STEP_0) { | ||
1342 | /* nothing */ | ||
1343 | } else if (*tune_state == CT_TUNER_STEP_1) { | ||
1344 | state->step /= 2; | ||
1345 | dib0090_write_reg(state, 0x18, lo4 | state->captrim); | ||
1346 | *tune_state = CT_TUNER_STEP_2; | ||
1347 | } else if (*tune_state == CT_TUNER_STEP_2) { | ||
1348 | |||
1349 | adc = dib0090_read_reg(state, 0x1d); | ||
1350 | dprintk("FE %d CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) fe->id, (u32) state->captrim, (u32) adc, | ||
1351 | (u32) (adc) * (u32) 1800 / (u32) 1024); | ||
1352 | |||
1353 | if (adc >= 400) { | ||
1354 | adc -= 400; | ||
1355 | step_sign = -1; | ||
1356 | } else { | ||
1357 | adc = 400 - adc; | ||
1358 | step_sign = 1; | ||
1359 | } | ||
1360 | |||
1361 | if (adc < state->adc_diff) { | ||
1362 | dprintk("FE %d CAPTRIM=%d is closer to target (%d/%d)", (u32) fe->id, (u32) state->captrim, (u32) adc, (u32) state->adc_diff); | ||
1363 | state->adc_diff = adc; | ||
1364 | state->fcaptrim = state->captrim; | ||
1365 | |||
1366 | } | ||
1367 | |||
1368 | state->captrim += step_sign * state->step; | ||
1369 | if (state->step >= 1) | ||
1370 | *tune_state = CT_TUNER_STEP_1; | ||
1371 | else | ||
1372 | *tune_state = CT_TUNER_STEP_3; | ||
1373 | |||
1374 | ret = 15; | ||
1375 | } else if (*tune_state == CT_TUNER_STEP_3) { | ||
1376 | /*write the final cptrim config */ | ||
1377 | dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim); | ||
1378 | |||
1379 | #ifdef CONFIG_TUNER_DIB0090_CAPTRIM_MEMORY | ||
1380 | state->memory[state->memory_index].cap = state->fcaptrim; | ||
1381 | #endif | ||
1382 | |||
1383 | *tune_state = CT_TUNER_STEP_4; | ||
1384 | } else if (*tune_state == CT_TUNER_STEP_4) { | ||
1385 | dib0090_write_reg(state, 0x1e, 0x07ff); | ||
1386 | |||
1387 | dprintk("FE %d Final Captrim: %d", (u32) fe->id, (u32) state->fcaptrim); | ||
1388 | dprintk("FE %d HFDIV code: %d", (u32) fe->id, (u32) pll->hfdiv_code); | ||
1389 | dprintk("FE %d VCO = %d", (u32) fe->id, (u32) pll->vco_band); | ||
1390 | dprintk("FE %d VCOF in kHz: %d ((%d*%d) << 1))", (u32) fe->id, (u32) ((pll->hfdiv * rf) * 2), (u32) pll->hfdiv, (u32) rf); | ||
1391 | dprintk("FE %d REFDIV: %d, FREF: %d", (u32) fe->id, (u32) 1, (u32) state->config->io.clock_khz); | ||
1392 | dprintk("FE %d FBDIV: %d, Rest: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17)); | ||
1393 | dprintk("FE %d Num: %d, Den: %d, SD: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x17), | ||
1394 | (u32) (dib0090_read_reg(state, 0x16) >> 8), (u32) dib0090_read_reg(state, 0x1c) & 0x3); | ||
1395 | |||
1396 | c = 4; | ||
1397 | i = 3; | ||
1398 | #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND) | ||
1399 | if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND)) { | ||
1400 | c = 2; | ||
1401 | i = 2; | ||
1402 | } | ||
1403 | #endif | ||
1404 | dib0090_write_reg(state, 0x10, (c << 13) | (i << 11) | (WBD | ||
1405 | #ifdef CONFIG_DIB0090_USE_PWM_AGC | ||
1406 | | (state->config->use_pwm_agc << 1) | ||
1407 | #endif | ||
1408 | )); | ||
1409 | dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | (tune->lna_bias << 0)); | ||
1410 | dib0090_write_reg(state, 0x0c, tune->v2i); | ||
1411 | dib0090_write_reg(state, 0x0d, tune->mix); | ||
1412 | dib0090_write_reg(state, 0x0e, tune->load); | ||
1413 | |||
1414 | *tune_state = CT_TUNER_STEP_5; | ||
1415 | } else if (*tune_state == CT_TUNER_STEP_5) { | ||
1416 | |||
1417 | /* initialize the lt gain register */ | ||
1418 | state->rf_lt_def = 0x7c00; | ||
1419 | dib0090_write_reg(state, 0x0f, state->rf_lt_def); | ||
1420 | |||
1421 | dib0090_set_bandwidth(state); | ||
1422 | state->tuner_is_tuned = 1; | ||
1423 | *tune_state = CT_TUNER_STOP; | ||
1424 | } else | ||
1425 | ret = FE_CALLBACK_TIME_NEVER; | ||
1426 | return ret; | ||
1427 | } | ||
1428 | |||
1429 | static int dib0090_release(struct dvb_frontend *fe) | ||
1430 | { | ||
1431 | kfree(fe->tuner_priv); | ||
1432 | fe->tuner_priv = NULL; | ||
1433 | return 0; | ||
1434 | } | ||
1435 | |||
1436 | enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) | ||
1437 | { | ||
1438 | struct dib0090_state *state = fe->tuner_priv; | ||
1439 | |||
1440 | return state->tune_state; | ||
1441 | } | ||
1442 | EXPORT_SYMBOL(dib0090_get_tune_state); | ||
1443 | |||
1444 | int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) | ||
1445 | { | ||
1446 | struct dib0090_state *state = fe->tuner_priv; | ||
1447 | |||
1448 | state->tune_state = tune_state; | ||
1449 | return 0; | ||
1450 | } | ||
1451 | EXPORT_SYMBOL(dib0090_set_tune_state); | ||
1452 | |||
1453 | static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency) | ||
1454 | { | ||
1455 | struct dib0090_state *state = fe->tuner_priv; | ||
1456 | |||
1457 | *frequency = 1000 * state->current_rf; | ||
1458 | return 0; | ||
1459 | } | ||
1460 | |||
1461 | static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | ||
1462 | { | ||
1463 | struct dib0090_state *state = fe->tuner_priv; | ||
1464 | uint32_t ret; | ||
1465 | |||
1466 | state->tune_state = CT_TUNER_START; | ||
1467 | |||
1468 | do { | ||
1469 | ret = dib0090_tune(fe); | ||
1470 | if (ret != FE_CALLBACK_TIME_NEVER) | ||
1471 | msleep(ret / 10); | ||
1472 | else | ||
1473 | break; | ||
1474 | } while (state->tune_state != CT_TUNER_STOP); | ||
1475 | |||
1476 | return 0; | ||
1477 | } | ||
1478 | |||
1479 | static const struct dvb_tuner_ops dib0090_ops = { | ||
1480 | .info = { | ||
1481 | .name = "DiBcom DiB0090", | ||
1482 | .frequency_min = 45000000, | ||
1483 | .frequency_max = 860000000, | ||
1484 | .frequency_step = 1000, | ||
1485 | }, | ||
1486 | .release = dib0090_release, | ||
1487 | |||
1488 | .init = dib0090_wakeup, | ||
1489 | .sleep = dib0090_sleep, | ||
1490 | .set_params = dib0090_set_params, | ||
1491 | .get_frequency = dib0090_get_frequency, | ||
1492 | }; | ||
1493 | |||
1494 | struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) | ||
1495 | { | ||
1496 | struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL); | ||
1497 | if (st == NULL) | ||
1498 | return NULL; | ||
1499 | |||
1500 | st->config = config; | ||
1501 | st->i2c = i2c; | ||
1502 | st->fe = fe; | ||
1503 | fe->tuner_priv = st; | ||
1504 | |||
1505 | if (dib0090_reset(fe) != 0) | ||
1506 | goto free_mem; | ||
1507 | |||
1508 | printk(KERN_INFO "DiB0090: successfully identified\n"); | ||
1509 | memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops)); | ||
1510 | |||
1511 | return fe; | ||
1512 | free_mem: | ||
1513 | kfree(st); | ||
1514 | fe->tuner_priv = NULL; | ||
1515 | return NULL; | ||
1516 | } | ||
1517 | EXPORT_SYMBOL(dib0090_register); | ||
1518 | |||
1519 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); | ||
1520 | MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>"); | ||
1521 | MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner"); | ||
1522 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h new file mode 100644 index 00000000000..aa7711e8877 --- /dev/null +++ b/drivers/media/dvb/frontends/dib0090.h | |||
@@ -0,0 +1,108 @@ | |||
1 | /* | ||
2 | * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner. | ||
3 | * | ||
4 | * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | */ | ||
10 | #ifndef DIB0090_H | ||
11 | #define DIB0090_H | ||
12 | |||
13 | struct dvb_frontend; | ||
14 | struct i2c_adapter; | ||
15 | |||
16 | #define DEFAULT_DIB0090_I2C_ADDRESS 0x60 | ||
17 | |||
18 | struct dib0090_io_config { | ||
19 | u32 clock_khz; | ||
20 | |||
21 | u8 pll_bypass:1; | ||
22 | u8 pll_range:1; | ||
23 | u8 pll_prediv:6; | ||
24 | u8 pll_loopdiv:6; | ||
25 | |||
26 | u8 adc_clock_ratio; /* valid is 8, 7 ,6 */ | ||
27 | u16 pll_int_loop_filt; | ||
28 | }; | ||
29 | |||
30 | struct dib0090_config { | ||
31 | struct dib0090_io_config io; | ||
32 | int (*reset) (struct dvb_frontend *, int); | ||
33 | int (*sleep) (struct dvb_frontend *, int); | ||
34 | |||
35 | /* offset in kHz */ | ||
36 | int freq_offset_khz_uhf; | ||
37 | int freq_offset_khz_vhf; | ||
38 | |||
39 | int (*get_adc_power) (struct dvb_frontend *); | ||
40 | |||
41 | u8 clkouttobamse:1; /* activate or deactivate clock output */ | ||
42 | u8 analog_output; | ||
43 | |||
44 | u8 i2c_address; | ||
45 | /* add drives and other things if necessary */ | ||
46 | u16 wbd_vhf_offset; | ||
47 | u16 wbd_cband_offset; | ||
48 | u8 use_pwm_agc; | ||
49 | u8 clkoutdrive; | ||
50 | }; | ||
51 | |||
52 | #if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE)) | ||
53 | extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); | ||
54 | extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); | ||
55 | extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe); | ||
56 | extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner); | ||
57 | extern int dib0090_gain_control(struct dvb_frontend *fe); | ||
58 | extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe); | ||
59 | extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state); | ||
60 | extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt); | ||
61 | #else | ||
62 | static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config) | ||
63 | { | ||
64 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
65 | return NULL; | ||
66 | } | ||
67 | |||
68 | static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) | ||
69 | { | ||
70 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
71 | } | ||
72 | |||
73 | static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe) | ||
74 | { | ||
75 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
76 | } | ||
77 | |||
78 | static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) | ||
79 | { | ||
80 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static inline int dib0090_gain_control(struct dvb_frontend *fe) | ||
85 | { | ||
86 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
87 | return -ENODEV; | ||
88 | } | ||
89 | |||
90 | static inline enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe) | ||
91 | { | ||
92 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
93 | return CT_DONE; | ||
94 | } | ||
95 | |||
96 | static inline int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) | ||
97 | { | ||
98 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
99 | return -ENODEV; | ||
100 | } | ||
101 | |||
102 | static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) | ||
103 | { | ||
104 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
105 | } | ||
106 | #endif | ||
107 | |||
108 | #endif | ||
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index 898400d331a..6f6fa29d9ea 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c | |||
@@ -28,18 +28,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); | |||
28 | 28 | ||
29 | #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0) | 29 | #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0) |
30 | 30 | ||
31 | enum frontend_tune_state { | ||
32 | CT_AGC_START = 20, | ||
33 | CT_AGC_STEP_0, | ||
34 | CT_AGC_STEP_1, | ||
35 | CT_AGC_STEP_2, | ||
36 | CT_AGC_STEP_3, | ||
37 | CT_AGC_STEP_4, | ||
38 | CT_AGC_STOP, | ||
39 | |||
40 | CT_DEMOD_START = 30, | ||
41 | }; | ||
42 | |||
43 | #define FE_STATUS_TUNE_FAILED 0 | 31 | #define FE_STATUS_TUNE_FAILED 0 |
44 | 32 | ||
45 | struct i2c_device { | 33 | struct i2c_device { |
@@ -133,104 +121,104 @@ static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) | |||
133 | return dib8000_i2c_write16(&state->i2c, reg, val); | 121 | return dib8000_i2c_write16(&state->i2c, reg, val); |
134 | } | 122 | } |
135 | 123 | ||
136 | const int16_t coeff_2k_sb_1seg_dqpsk[8] = { | 124 | static const int16_t coeff_2k_sb_1seg_dqpsk[8] = { |
137 | (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c, | 125 | (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c, |
138 | (920 << 5) | 0x09 | 126 | (920 << 5) | 0x09 |
139 | }; | 127 | }; |
140 | 128 | ||
141 | const int16_t coeff_2k_sb_1seg[8] = { | 129 | static const int16_t coeff_2k_sb_1seg[8] = { |
142 | (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f | 130 | (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f |
143 | }; | 131 | }; |
144 | 132 | ||
145 | const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = { | 133 | static const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = { |
146 | (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11, | 134 | (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11, |
147 | (-931 << 5) | 0x0f | 135 | (-931 << 5) | 0x0f |
148 | }; | 136 | }; |
149 | 137 | ||
150 | const int16_t coeff_2k_sb_3seg_0dqpsk[8] = { | 138 | static const int16_t coeff_2k_sb_3seg_0dqpsk[8] = { |
151 | (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e, | 139 | (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e, |
152 | (982 << 5) | 0x0c | 140 | (982 << 5) | 0x0c |
153 | }; | 141 | }; |
154 | 142 | ||
155 | const int16_t coeff_2k_sb_3seg_1dqpsk[8] = { | 143 | static const int16_t coeff_2k_sb_3seg_1dqpsk[8] = { |
156 | (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12, | 144 | (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12, |
157 | (-720 << 5) | 0x0d | 145 | (-720 << 5) | 0x0d |
158 | }; | 146 | }; |
159 | 147 | ||
160 | const int16_t coeff_2k_sb_3seg[8] = { | 148 | static const int16_t coeff_2k_sb_3seg[8] = { |
161 | (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e, | 149 | (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e, |
162 | (-610 << 5) | 0x0a | 150 | (-610 << 5) | 0x0a |
163 | }; | 151 | }; |
164 | 152 | ||
165 | const int16_t coeff_4k_sb_1seg_dqpsk[8] = { | 153 | static const int16_t coeff_4k_sb_1seg_dqpsk[8] = { |
166 | (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f, | 154 | (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f, |
167 | (-922 << 5) | 0x0d | 155 | (-922 << 5) | 0x0d |
168 | }; | 156 | }; |
169 | 157 | ||
170 | const int16_t coeff_4k_sb_1seg[8] = { | 158 | static const int16_t coeff_4k_sb_1seg[8] = { |
171 | (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d, | 159 | (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d, |
172 | (-655 << 5) | 0x0a | 160 | (-655 << 5) | 0x0a |
173 | }; | 161 | }; |
174 | 162 | ||
175 | const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = { | 163 | static const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = { |
176 | (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14, | 164 | (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14, |
177 | (-958 << 5) | 0x13 | 165 | (-958 << 5) | 0x13 |
178 | }; | 166 | }; |
179 | 167 | ||
180 | const int16_t coeff_4k_sb_3seg_0dqpsk[8] = { | 168 | static const int16_t coeff_4k_sb_3seg_0dqpsk[8] = { |
181 | (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12, | 169 | (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12, |
182 | (-568 << 5) | 0x0f | 170 | (-568 << 5) | 0x0f |
183 | }; | 171 | }; |
184 | 172 | ||
185 | const int16_t coeff_4k_sb_3seg_1dqpsk[8] = { | 173 | static const int16_t coeff_4k_sb_3seg_1dqpsk[8] = { |
186 | (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14, | 174 | (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14, |
187 | (-848 << 5) | 0x13 | 175 | (-848 << 5) | 0x13 |
188 | }; | 176 | }; |
189 | 177 | ||
190 | const int16_t coeff_4k_sb_3seg[8] = { | 178 | static const int16_t coeff_4k_sb_3seg[8] = { |
191 | (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12, | 179 | (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12, |
192 | (-869 << 5) | 0x13 | 180 | (-869 << 5) | 0x13 |
193 | }; | 181 | }; |
194 | 182 | ||
195 | const int16_t coeff_8k_sb_1seg_dqpsk[8] = { | 183 | static const int16_t coeff_8k_sb_1seg_dqpsk[8] = { |
196 | (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13, | 184 | (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13, |
197 | (-598 << 5) | 0x10 | 185 | (-598 << 5) | 0x10 |
198 | }; | 186 | }; |
199 | 187 | ||
200 | const int16_t coeff_8k_sb_1seg[8] = { | 188 | static const int16_t coeff_8k_sb_1seg[8] = { |
201 | (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f, | 189 | (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f, |
202 | (585 << 5) | 0x0f | 190 | (585 << 5) | 0x0f |
203 | }; | 191 | }; |
204 | 192 | ||
205 | const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = { | 193 | static const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = { |
206 | (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18, | 194 | (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18, |
207 | (0 << 5) | 0x14 | 195 | (0 << 5) | 0x14 |
208 | }; | 196 | }; |
209 | 197 | ||
210 | const int16_t coeff_8k_sb_3seg_0dqpsk[8] = { | 198 | static const int16_t coeff_8k_sb_3seg_0dqpsk[8] = { |
211 | (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15, | 199 | (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15, |
212 | (-877 << 5) | 0x15 | 200 | (-877 << 5) | 0x15 |
213 | }; | 201 | }; |
214 | 202 | ||
215 | const int16_t coeff_8k_sb_3seg_1dqpsk[8] = { | 203 | static const int16_t coeff_8k_sb_3seg_1dqpsk[8] = { |
216 | (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18, | 204 | (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18, |
217 | (-921 << 5) | 0x14 | 205 | (-921 << 5) | 0x14 |
218 | }; | 206 | }; |
219 | 207 | ||
220 | const int16_t coeff_8k_sb_3seg[8] = { | 208 | static const int16_t coeff_8k_sb_3seg[8] = { |
221 | (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15, | 209 | (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15, |
222 | (690 << 5) | 0x14 | 210 | (690 << 5) | 0x14 |
223 | }; | 211 | }; |
224 | 212 | ||
225 | const int16_t ana_fe_coeff_3seg[24] = { | 213 | static const int16_t ana_fe_coeff_3seg[24] = { |
226 | 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017 | 214 | 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017 |
227 | }; | 215 | }; |
228 | 216 | ||
229 | const int16_t ana_fe_coeff_1seg[24] = { | 217 | static const int16_t ana_fe_coeff_1seg[24] = { |
230 | 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003 | 218 | 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003 |
231 | }; | 219 | }; |
232 | 220 | ||
233 | const int16_t ana_fe_coeff_13seg[24] = { | 221 | static const int16_t ana_fe_coeff_13seg[24] = { |
234 | 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1 | 222 | 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1 |
235 | }; | 223 | }; |
236 | 224 | ||
@@ -852,6 +840,14 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band) | |||
852 | return 0; | 840 | return 0; |
853 | } | 841 | } |
854 | 842 | ||
843 | void dib8000_pwm_agc_reset(struct dvb_frontend *fe) | ||
844 | { | ||
845 | struct dib8000_state *state = fe->demodulator_priv; | ||
846 | dib8000_set_adc_state(state, DIBX000_ADC_ON); | ||
847 | dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))); | ||
848 | } | ||
849 | EXPORT_SYMBOL(dib8000_pwm_agc_reset); | ||
850 | |||
855 | static int dib8000_agc_soft_split(struct dib8000_state *state) | 851 | static int dib8000_agc_soft_split(struct dib8000_state *state) |
856 | { | 852 | { |
857 | u16 agc, split_offset; | 853 | u16 agc, split_offset; |
@@ -939,6 +935,32 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) | |||
939 | 935 | ||
940 | } | 936 | } |
941 | 937 | ||
938 | static const int32_t lut_1000ln_mant[] = | ||
939 | { | ||
940 | 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 | ||
941 | }; | ||
942 | |||
943 | int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode) | ||
944 | { | ||
945 | struct dib8000_state *state = fe->demodulator_priv; | ||
946 | uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0; | ||
947 | int32_t val; | ||
948 | |||
949 | val = dib8000_read32(state, 384); | ||
950 | /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */ | ||
951 | if (mode) { | ||
952 | tmp_val = val; | ||
953 | while (tmp_val >>= 1) | ||
954 | exp++; | ||
955 | mant = (val * 1000 / (1<<exp)); | ||
956 | ix = (uint8_t)((mant-1000)/100); /* index of the LUT */ | ||
957 | val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); /* 1000 * ln(adcpower_real) ; 693 = 1000ln(2) ; 6908 = 1000*ln(1000) ; 20 comes from adc_real = adc_pow_int / 2**20 */ | ||
958 | val = (val*256)/1000; | ||
959 | } | ||
960 | return val; | ||
961 | } | ||
962 | EXPORT_SYMBOL(dib8000_get_adc_power); | ||
963 | |||
942 | static void dib8000_update_timf(struct dib8000_state *state) | 964 | static void dib8000_update_timf(struct dib8000_state *state) |
943 | { | 965 | { |
944 | u32 timf = state->timf = dib8000_read32(state, 435); | 966 | u32 timf = state->timf = dib8000_read32(state, 435); |
@@ -1401,10 +1423,9 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1401 | } | 1423 | } |
1402 | break; | 1424 | break; |
1403 | } | 1425 | } |
1404 | } | ||
1405 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) | ||
1406 | for (i = 0; i < 8; i++) | 1426 | for (i = 0; i < 8; i++) |
1407 | dib8000_write_word(state, 343 + i, ncoeff[i]); | 1427 | dib8000_write_word(state, 343 + i, ncoeff[i]); |
1428 | } | ||
1408 | 1429 | ||
1409 | // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 | 1430 | // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 |
1410 | dib8000_write_word(state, 351, | 1431 | dib8000_write_word(state, 351, |
@@ -1854,6 +1875,24 @@ static int dib8000_sleep(struct dvb_frontend *fe) | |||
1854 | } | 1875 | } |
1855 | } | 1876 | } |
1856 | 1877 | ||
1878 | enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) | ||
1879 | { | ||
1880 | struct dib8000_state *state = fe->demodulator_priv; | ||
1881 | return state->tune_state; | ||
1882 | } | ||
1883 | EXPORT_SYMBOL(dib8000_get_tune_state); | ||
1884 | |||
1885 | int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) | ||
1886 | { | ||
1887 | struct dib8000_state *state = fe->demodulator_priv; | ||
1888 | state->tune_state = tune_state; | ||
1889 | return 0; | ||
1890 | } | ||
1891 | EXPORT_SYMBOL(dib8000_set_tune_state); | ||
1892 | |||
1893 | |||
1894 | |||
1895 | |||
1857 | static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | 1896 | static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) |
1858 | { | 1897 | { |
1859 | struct dib8000_state *state = fe->demodulator_priv; | 1898 | struct dib8000_state *state = fe->demodulator_priv; |
@@ -2043,29 +2082,31 @@ static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) | |||
2043 | 2082 | ||
2044 | *stat = 0; | 2083 | *stat = 0; |
2045 | 2084 | ||
2046 | if ((lock >> 14) & 1) // AGC | 2085 | if ((lock >> 13) & 1) |
2047 | *stat |= FE_HAS_SIGNAL; | 2086 | *stat |= FE_HAS_SIGNAL; |
2048 | 2087 | ||
2049 | if ((lock >> 8) & 1) // Equal | 2088 | if ((lock >> 8) & 1) /* Equal */ |
2050 | *stat |= FE_HAS_CARRIER; | 2089 | *stat |= FE_HAS_CARRIER; |
2051 | 2090 | ||
2052 | if ((lock >> 3) & 1) // TMCC_SYNC | 2091 | if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */ |
2053 | *stat |= FE_HAS_SYNC; | 2092 | *stat |= FE_HAS_SYNC; |
2054 | 2093 | ||
2055 | if ((lock >> 5) & 7) // FEC MPEG | 2094 | if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */ |
2056 | *stat |= FE_HAS_LOCK; | 2095 | *stat |= FE_HAS_LOCK; |
2057 | 2096 | ||
2058 | lock = dib8000_read_word(state, 554); // Viterbi Layer A | 2097 | if ((lock >> 12) & 1) { |
2059 | if (lock & 0x01) | 2098 | lock = dib8000_read_word(state, 554); /* Viterbi Layer A */ |
2060 | *stat |= FE_HAS_VITERBI; | 2099 | if (lock & 0x01) |
2100 | *stat |= FE_HAS_VITERBI; | ||
2061 | 2101 | ||
2062 | lock = dib8000_read_word(state, 555); // Viterbi Layer B | 2102 | lock = dib8000_read_word(state, 555); /* Viterbi Layer B */ |
2063 | if (lock & 0x01) | 2103 | if (lock & 0x01) |
2064 | *stat |= FE_HAS_VITERBI; | 2104 | *stat |= FE_HAS_VITERBI; |
2065 | 2105 | ||
2066 | lock = dib8000_read_word(state, 556); // Viterbi Layer C | 2106 | lock = dib8000_read_word(state, 556); /* Viterbi Layer C */ |
2067 | if (lock & 0x01) | 2107 | if (lock & 0x01) |
2068 | *stat |= FE_HAS_VITERBI; | 2108 | *stat |= FE_HAS_VITERBI; |
2109 | } | ||
2069 | 2110 | ||
2070 | return 0; | 2111 | return 0; |
2071 | } | 2112 | } |
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index 8c89482b738..d99619ae983 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h | |||
@@ -46,6 +46,10 @@ extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); | |||
46 | extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); | 46 | extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); |
47 | extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff); | 47 | extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff); |
48 | extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); | 48 | extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); |
49 | extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state); | ||
50 | extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); | ||
51 | extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); | ||
52 | extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); | ||
49 | #else | 53 | #else |
50 | static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) | 54 | static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) |
51 | { | 55 | { |
@@ -59,35 +63,53 @@ static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe | |||
59 | return NULL; | 63 | return NULL; |
60 | } | 64 | } |
61 | 65 | ||
62 | int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) | 66 | static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) |
63 | { | 67 | { |
64 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 68 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
65 | return -ENODEV; | 69 | return -ENODEV; |
66 | } | 70 | } |
67 | 71 | ||
68 | int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) | 72 | static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) |
69 | { | 73 | { |
70 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 74 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
71 | return -ENODEV; | 75 | return -ENODEV; |
72 | } | 76 | } |
73 | 77 | ||
74 | int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) | 78 | static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value) |
75 | { | 79 | { |
76 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 80 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
77 | return -ENODEV; | 81 | return -ENODEV; |
78 | } | 82 | } |
79 | 83 | ||
80 | int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) | 84 | static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) |
81 | { | 85 | { |
82 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 86 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
83 | return -ENODEV; | 87 | return -ENODEV; |
84 | } | 88 | } |
85 | 89 | ||
86 | int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) | 90 | static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) |
87 | { | 91 | { |
88 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 92 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
89 | return -ENODEV; | 93 | return -ENODEV; |
90 | } | 94 | } |
95 | static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) | ||
96 | { | ||
97 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
98 | return -ENODEV; | ||
99 | } | ||
100 | static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) | ||
101 | { | ||
102 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
103 | return CT_SHUTDOWN, | ||
104 | } | ||
105 | static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe) | ||
106 | { | ||
107 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
108 | } | ||
109 | static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) | ||
110 | { | ||
111 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
112 | } | ||
91 | #endif | 113 | #endif |
92 | 114 | ||
93 | #endif | 115 | #endif |
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index 4efca30d212..e6f3d73db9d 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c | |||
@@ -6,7 +6,7 @@ static int debug; | |||
6 | module_param(debug, int, 0644); | 6 | module_param(debug, int, 0644); |
7 | MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); | 7 | MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); |
8 | 8 | ||
9 | #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0) | 9 | #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0) |
10 | 10 | ||
11 | static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) | 11 | static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) |
12 | { | 12 | { |
@@ -25,7 +25,7 @@ static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, | |||
25 | enum dibx000_i2c_interface intf) | 25 | enum dibx000_i2c_interface intf) |
26 | { | 26 | { |
27 | if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) { | 27 | if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) { |
28 | dprintk("selecting interface: %d\n", intf); | 28 | dprintk("selecting interface: %d", intf); |
29 | mst->selected_interface = intf; | 29 | mst->selected_interface = intf; |
30 | return dibx000_write_word(mst, mst->base_reg + 4, intf); | 30 | return dibx000_write_word(mst, mst->base_reg + 4, intf); |
31 | } | 31 | } |
@@ -171,9 +171,18 @@ void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) | |||
171 | { | 171 | { |
172 | i2c_del_adapter(&mst->gated_tuner_i2c_adap); | 172 | i2c_del_adapter(&mst->gated_tuner_i2c_adap); |
173 | } | 173 | } |
174 | |||
175 | EXPORT_SYMBOL(dibx000_exit_i2c_master); | 174 | EXPORT_SYMBOL(dibx000_exit_i2c_master); |
176 | 175 | ||
176 | |||
177 | u32 systime() | ||
178 | { | ||
179 | struct timespec t; | ||
180 | |||
181 | t = current_kernel_time(); | ||
182 | return (t.tv_sec * 10000) + (t.tv_nsec / 100000); | ||
183 | } | ||
184 | EXPORT_SYMBOL(systime); | ||
185 | |||
177 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); | 186 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); |
178 | MODULE_DESCRIPTION("Common function the DiBcom demodulator family"); | 187 | MODULE_DESCRIPTION("Common function the DiBcom demodulator family"); |
179 | MODULE_LICENSE("GPL"); | 188 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h index 5be10eca07c..4f5d141a308 100644 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ b/drivers/media/dvb/frontends/dibx000_common.h | |||
@@ -36,13 +36,17 @@ extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master | |||
36 | extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); | 36 | extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); |
37 | extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst); | 37 | extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst); |
38 | 38 | ||
39 | extern u32 systime(void); | ||
40 | |||
39 | #define BAND_LBAND 0x01 | 41 | #define BAND_LBAND 0x01 |
40 | #define BAND_UHF 0x02 | 42 | #define BAND_UHF 0x02 |
41 | #define BAND_VHF 0x04 | 43 | #define BAND_VHF 0x04 |
42 | #define BAND_SBAND 0x08 | 44 | #define BAND_SBAND 0x08 |
43 | #define BAND_FM 0x10 | 45 | #define BAND_FM 0x10 |
46 | #define BAND_CBAND 0x20 | ||
44 | 47 | ||
45 | #define BAND_OF_FREQUENCY(freq_kHz) ( (freq_kHz) <= 115000 ? BAND_FM : \ | 48 | #define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \ |
49 | (freq_kHz) <= 115000 ? BAND_FM : \ | ||
46 | (freq_kHz) <= 250000 ? BAND_VHF : \ | 50 | (freq_kHz) <= 250000 ? BAND_VHF : \ |
47 | (freq_kHz) <= 863000 ? BAND_UHF : \ | 51 | (freq_kHz) <= 863000 ? BAND_UHF : \ |
48 | (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND ) | 52 | (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND ) |
@@ -149,4 +153,67 @@ enum dibx000_adc_states { | |||
149 | #define OUTMODE_MPEG2_FIFO 5 | 153 | #define OUTMODE_MPEG2_FIFO 5 |
150 | #define OUTMODE_ANALOG_ADC 6 | 154 | #define OUTMODE_ANALOG_ADC 6 |
151 | 155 | ||
156 | enum frontend_tune_state { | ||
157 | CT_TUNER_START = 10, | ||
158 | CT_TUNER_STEP_0, | ||
159 | CT_TUNER_STEP_1, | ||
160 | CT_TUNER_STEP_2, | ||
161 | CT_TUNER_STEP_3, | ||
162 | CT_TUNER_STEP_4, | ||
163 | CT_TUNER_STEP_5, | ||
164 | CT_TUNER_STEP_6, | ||
165 | CT_TUNER_STEP_7, | ||
166 | CT_TUNER_STOP, | ||
167 | |||
168 | CT_AGC_START = 20, | ||
169 | CT_AGC_STEP_0, | ||
170 | CT_AGC_STEP_1, | ||
171 | CT_AGC_STEP_2, | ||
172 | CT_AGC_STEP_3, | ||
173 | CT_AGC_STEP_4, | ||
174 | CT_AGC_STOP, | ||
175 | |||
176 | CT_DEMOD_START = 30, | ||
177 | CT_DEMOD_STEP_1, | ||
178 | CT_DEMOD_STEP_2, | ||
179 | CT_DEMOD_STEP_3, | ||
180 | CT_DEMOD_STEP_4, | ||
181 | CT_DEMOD_STEP_5, | ||
182 | CT_DEMOD_STEP_6, | ||
183 | CT_DEMOD_STEP_7, | ||
184 | CT_DEMOD_STEP_8, | ||
185 | CT_DEMOD_STEP_9, | ||
186 | CT_DEMOD_STEP_10, | ||
187 | CT_DEMOD_SEARCH_NEXT = 41, | ||
188 | CT_DEMOD_STEP_LOCKED, | ||
189 | CT_DEMOD_STOP, | ||
190 | |||
191 | CT_DONE = 100, | ||
192 | CT_SHUTDOWN, | ||
193 | |||
194 | }; | ||
195 | |||
196 | struct dvb_frontend_parametersContext { | ||
197 | #define CHANNEL_STATUS_PARAMETERS_UNKNOWN 0x01 | ||
198 | #define CHANNEL_STATUS_PARAMETERS_SET 0x02 | ||
199 | u8 status; | ||
200 | u32 tune_time_estimation[2]; | ||
201 | s32 tps_available; | ||
202 | u16 tps[9]; | ||
203 | }; | ||
204 | |||
205 | #define FE_STATUS_TUNE_FAILED 0 | ||
206 | #define FE_STATUS_TUNE_TIMED_OUT -1 | ||
207 | #define FE_STATUS_TUNE_TIME_TOO_SHORT -2 | ||
208 | #define FE_STATUS_TUNE_PENDING -3 | ||
209 | #define FE_STATUS_STD_SUCCESS -4 | ||
210 | #define FE_STATUS_FFT_SUCCESS -5 | ||
211 | #define FE_STATUS_DEMOD_SUCCESS -6 | ||
212 | #define FE_STATUS_LOCKED -7 | ||
213 | #define FE_STATUS_DATA_LOCKED -8 | ||
214 | |||
215 | #define FE_CALLBACK_TIME_NEVER 0xffffffff | ||
216 | |||
217 | #define ABS(x) ((x < 0) ? (-x) : (x)) | ||
218 | |||
152 | #endif | 219 | #endif |
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c index eabcadc425d..dee53960e7e 100644 --- a/drivers/media/dvb/frontends/lgs8gxx.c +++ b/drivers/media/dvb/frontends/lgs8gxx.c | |||
@@ -199,7 +199,7 @@ static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/) | |||
199 | 199 | ||
200 | val = freq; | 200 | val = freq; |
201 | if (freq != 0) { | 201 | if (freq != 0) { |
202 | val *= (u64)1 << 32; | 202 | val <<= 32; |
203 | if (if_clk != 0) | 203 | if (if_clk != 0) |
204 | do_div(val, if_clk); | 204 | do_div(val, if_clk); |
205 | v32 = val & 0xFFFFFFFF; | 205 | v32 = val & 0xFFFFFFFF; |
@@ -246,7 +246,7 @@ static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv) | |||
246 | 246 | ||
247 | val = v32; | 247 | val = v32; |
248 | val *= priv->config->if_clk_freq; | 248 | val *= priv->config->if_clk_freq; |
249 | val /= (u64)1 << 32; | 249 | val >>= 32; |
250 | dprintk("AFC = %u kHz\n", (u32)val); | 250 | dprintk("AFC = %u kHz\n", (u32)val); |
251 | return 0; | 251 | return 0; |
252 | } | 252 | } |
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c index 71f607fe8fc..b181bf023ad 100644 --- a/drivers/media/dvb/frontends/lnbp21.c +++ b/drivers/media/dvb/frontends/lnbp21.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * lnbp21.c - driver for lnb supply and control ic lnbp21 | 2 | * lnbp21.c - driver for lnb supply and control ic lnbp21 |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Oliver Endriss | 4 | * Copyright (C) 2006, 2009 Oliver Endriss <o.endriss@gmx.de> |
5 | * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> | 5 | * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
@@ -91,6 +91,31 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | |||
91 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | 91 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; |
92 | } | 92 | } |
93 | 93 | ||
94 | static int lnbp21_set_tone(struct dvb_frontend *fe, | ||
95 | fe_sec_tone_mode_t tone) | ||
96 | { | ||
97 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; | ||
98 | struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0, | ||
99 | .buf = &lnbp21->config, | ||
100 | .len = sizeof(lnbp21->config) }; | ||
101 | |||
102 | switch (tone) { | ||
103 | case SEC_TONE_OFF: | ||
104 | lnbp21->config &= ~LNBP21_TEN; | ||
105 | break; | ||
106 | case SEC_TONE_ON: | ||
107 | lnbp21->config |= LNBP21_TEN; | ||
108 | break; | ||
109 | default: | ||
110 | return -EINVAL; | ||
111 | }; | ||
112 | |||
113 | lnbp21->config |= lnbp21->override_or; | ||
114 | lnbp21->config &= lnbp21->override_and; | ||
115 | |||
116 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
117 | } | ||
118 | |||
94 | static void lnbp21_release(struct dvb_frontend *fe) | 119 | static void lnbp21_release(struct dvb_frontend *fe) |
95 | { | 120 | { |
96 | /* LNBP power off */ | 121 | /* LNBP power off */ |
@@ -133,6 +158,7 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, | |||
133 | /* override frontend ops */ | 158 | /* override frontend ops */ |
134 | fe->ops.set_voltage = lnbp21_set_voltage; | 159 | fe->ops.set_voltage = lnbp21_set_voltage; |
135 | fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | 160 | fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; |
161 | fe->ops.set_tone = lnbp21_set_tone; | ||
136 | printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr); | 162 | printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr); |
137 | 163 | ||
138 | return fe; | 164 | return fe; |
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index df49ea0983b..8762c86044a 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c | |||
@@ -1451,6 +1451,8 @@ static int stv0900_status(struct stv0900_internal *intp, | |||
1451 | { | 1451 | { |
1452 | enum fe_stv0900_search_state demod_state; | 1452 | enum fe_stv0900_search_state demod_state; |
1453 | int locked = FALSE; | 1453 | int locked = FALSE; |
1454 | u8 tsbitrate0_val, tsbitrate1_val; | ||
1455 | s32 bitrate; | ||
1454 | 1456 | ||
1455 | demod_state = stv0900_get_bits(intp, HEADER_MODE); | 1457 | demod_state = stv0900_get_bits(intp, HEADER_MODE); |
1456 | switch (demod_state) { | 1458 | switch (demod_state) { |
@@ -1473,6 +1475,17 @@ static int stv0900_status(struct stv0900_internal *intp, | |||
1473 | 1475 | ||
1474 | dprintk("%s: locked = %d\n", __func__, locked); | 1476 | dprintk("%s: locked = %d\n", __func__, locked); |
1475 | 1477 | ||
1478 | if (stvdebug) { | ||
1479 | /* Print TS bitrate */ | ||
1480 | tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0); | ||
1481 | tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1); | ||
1482 | /* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */ | ||
1483 | bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000) | ||
1484 | * (tsbitrate1_val << 8 | tsbitrate0_val); | ||
1485 | bitrate /= 16384; | ||
1486 | dprintk("TS bitrate = %d Mbit/sec \n", bitrate); | ||
1487 | }; | ||
1488 | |||
1476 | return locked; | 1489 | return locked; |
1477 | } | 1490 | } |
1478 | 1491 | ||
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 48edd542242..1573466a5c7 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c | |||
@@ -3597,7 +3597,8 @@ static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma | |||
3597 | 3597 | ||
3598 | reg = STV090x_READ_DEMOD(state, DISTXCTL); | 3598 | reg = STV090x_READ_DEMOD(state, DISTXCTL); |
3599 | 3599 | ||
3600 | STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 2); | 3600 | STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, |
3601 | (state->config->diseqc_envelope_mode) ? 4 : 2); | ||
3601 | STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); | 3602 | STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); |
3602 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) | 3603 | if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) |
3603 | goto err; | 3604 | goto err; |
@@ -3649,10 +3650,10 @@ static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t | |||
3649 | reg = STV090x_READ_DEMOD(state, DISTXCTL); | 3650 | reg = STV090x_READ_DEMOD(state, DISTXCTL); |
3650 | 3651 | ||
3651 | if (burst == SEC_MINI_A) { | 3652 | if (burst == SEC_MINI_A) { |
3652 | mode = 3; | 3653 | mode = (state->config->diseqc_envelope_mode) ? 5 : 3; |
3653 | value = 0x00; | 3654 | value = 0x00; |
3654 | } else { | 3655 | } else { |
3655 | mode = 2; | 3656 | mode = (state->config->diseqc_envelope_mode) ? 4 : 2; |
3656 | value = 0xFF; | 3657 | value = 0xFF; |
3657 | } | 3658 | } |
3658 | 3659 | ||
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h index e968c98bb70..b133807663e 100644 --- a/drivers/media/dvb/frontends/stv090x.h +++ b/drivers/media/dvb/frontends/stv090x.h | |||
@@ -75,6 +75,8 @@ struct stv090x_config { | |||
75 | 75 | ||
76 | enum stv090x_i2crpt repeater_level; | 76 | enum stv090x_i2crpt repeater_level; |
77 | 77 | ||
78 | bool diseqc_envelope_mode; | ||
79 | |||
78 | int (*tuner_init) (struct dvb_frontend *fe); | 80 | int (*tuner_init) (struct dvb_frontend *fe); |
79 | int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); | 81 | int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); |
80 | int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); | 82 | int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); |
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 266033ae278..68bf9fbd8fe 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c | |||
@@ -662,7 +662,7 @@ adapter_error: | |||
662 | return rc; | 662 | return rc; |
663 | } | 663 | } |
664 | 664 | ||
665 | int smsdvb_module_init(void) | 665 | static int __init smsdvb_module_init(void) |
666 | { | 666 | { |
667 | int rc; | 667 | int rc; |
668 | 668 | ||
@@ -676,7 +676,7 @@ int smsdvb_module_init(void) | |||
676 | return rc; | 676 | return rc; |
677 | } | 677 | } |
678 | 678 | ||
679 | void smsdvb_module_exit(void) | 679 | static void __exit smsdvb_module_exit(void) |
680 | { | 680 | { |
681 | smscore_unregister_hotplug(smsdvb_hotplug); | 681 | smscore_unregister_hotplug(smsdvb_hotplug); |
682 | 682 | ||
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c index 24206cbda26..195244a3e69 100644 --- a/drivers/media/dvb/siano/smssdio.c +++ b/drivers/media/dvb/siano/smssdio.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #define SMSSDIO_INT 0x04 | 48 | #define SMSSDIO_INT 0x04 |
49 | #define SMSSDIO_BLOCK_SIZE 128 | 49 | #define SMSSDIO_BLOCK_SIZE 128 |
50 | 50 | ||
51 | static const struct sdio_device_id smssdio_ids[] = { | 51 | static const struct sdio_device_id smssdio_ids[] __devinitconst = { |
52 | {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR), | 52 | {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR), |
53 | .driver_data = SMS1XXX_BOARD_SIANO_STELLAR}, | 53 | .driver_data = SMS1XXX_BOARD_SIANO_STELLAR}, |
54 | {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0), | 54 | {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0), |
@@ -222,7 +222,7 @@ static void smssdio_interrupt(struct sdio_func *func) | |||
222 | smscore_onresponse(smsdev->coredev, cb); | 222 | smscore_onresponse(smsdev->coredev, cb); |
223 | } | 223 | } |
224 | 224 | ||
225 | static int smssdio_probe(struct sdio_func *func, | 225 | static int __devinit smssdio_probe(struct sdio_func *func, |
226 | const struct sdio_device_id *id) | 226 | const struct sdio_device_id *id) |
227 | { | 227 | { |
228 | int ret; | 228 | int ret; |
@@ -338,7 +338,7 @@ static struct sdio_driver smssdio_driver = { | |||
338 | /* Module functions */ | 338 | /* Module functions */ |
339 | /*******************************************************************/ | 339 | /*******************************************************************/ |
340 | 340 | ||
341 | int smssdio_module_init(void) | 341 | static int __init smssdio_module_init(void) |
342 | { | 342 | { |
343 | int ret = 0; | 343 | int ret = 0; |
344 | 344 | ||
@@ -350,7 +350,7 @@ int smssdio_module_init(void) | |||
350 | return ret; | 350 | return ret; |
351 | } | 351 | } |
352 | 352 | ||
353 | void smssdio_module_exit(void) | 353 | static void __exit smssdio_module_exit(void) |
354 | { | 354 | { |
355 | sdio_unregister_driver(&smssdio_driver); | 355 | sdio_unregister_driver(&smssdio_driver); |
356 | } | 356 | } |
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 8f88a586b0d..5eac27287d9 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c | |||
@@ -390,7 +390,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) | |||
390 | return rc; | 390 | return rc; |
391 | } | 391 | } |
392 | 392 | ||
393 | static int smsusb_probe(struct usb_interface *intf, | 393 | static int __devinit smsusb_probe(struct usb_interface *intf, |
394 | const struct usb_device_id *id) | 394 | const struct usb_device_id *id) |
395 | { | 395 | { |
396 | struct usb_device *udev = interface_to_usbdev(intf); | 396 | struct usb_device *udev = interface_to_usbdev(intf); |
@@ -484,7 +484,7 @@ static int smsusb_resume(struct usb_interface *intf) | |||
484 | return 0; | 484 | return 0; |
485 | } | 485 | } |
486 | 486 | ||
487 | struct usb_device_id smsusb_id_table[] = { | 487 | static const struct usb_device_id smsusb_id_table[] __devinitconst = { |
488 | { USB_DEVICE(0x187f, 0x0010), | 488 | { USB_DEVICE(0x187f, 0x0010), |
489 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, | 489 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, |
490 | { USB_DEVICE(0x187f, 0x0100), | 490 | { USB_DEVICE(0x187f, 0x0100), |
@@ -533,8 +533,18 @@ struct usb_device_id smsusb_id_table[] = { | |||
533 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | 533 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, |
534 | { USB_DEVICE(0x2040, 0xb910), | 534 | { USB_DEVICE(0x2040, 0xb910), |
535 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | 535 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, |
536 | { USB_DEVICE(0x2040, 0xb980), | ||
537 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||
538 | { USB_DEVICE(0x2040, 0xb990), | ||
539 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||
536 | { USB_DEVICE(0x2040, 0xc000), | 540 | { USB_DEVICE(0x2040, 0xc000), |
537 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | 541 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, |
542 | { USB_DEVICE(0x2040, 0xc010), | ||
543 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||
544 | { USB_DEVICE(0x2040, 0xc080), | ||
545 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||
546 | { USB_DEVICE(0x2040, 0xc090), | ||
547 | .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, | ||
538 | { } /* Terminating entry */ | 548 | { } /* Terminating entry */ |
539 | }; | 549 | }; |
540 | 550 | ||
@@ -550,7 +560,7 @@ static struct usb_driver smsusb_driver = { | |||
550 | .resume = smsusb_resume, | 560 | .resume = smsusb_resume, |
551 | }; | 561 | }; |
552 | 562 | ||
553 | int smsusb_module_init(void) | 563 | static int __init smsusb_module_init(void) |
554 | { | 564 | { |
555 | int rc = usb_register(&smsusb_driver); | 565 | int rc = usb_register(&smsusb_driver); |
556 | if (rc) | 566 | if (rc) |
@@ -561,7 +571,7 @@ int smsusb_module_init(void) | |||
561 | return rc; | 571 | return rc; |
562 | } | 572 | } |
563 | 573 | ||
564 | void smsusb_module_exit(void) | 574 | static void __exit smsusb_module_exit(void) |
565 | { | 575 | { |
566 | /* Regular USB Cleanup */ | 576 | /* Regular USB Cleanup */ |
567 | usb_deregister(&smsusb_driver); | 577 | usb_deregister(&smsusb_driver); |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 7d193ebc0ae..9782e059373 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -190,12 +190,13 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
190 | struct saa7146_dev *saa = budget_ci->budget.dev; | 190 | struct saa7146_dev *saa = budget_ci->budget.dev; |
191 | struct input_dev *input_dev = budget_ci->ir.dev; | 191 | struct input_dev *input_dev = budget_ci->ir.dev; |
192 | int error; | 192 | int error; |
193 | struct ir_scancode_table *ir_codes; | ||
194 | |||
193 | 195 | ||
194 | budget_ci->ir.dev = input_dev = input_allocate_device(); | 196 | budget_ci->ir.dev = input_dev = input_allocate_device(); |
195 | if (!input_dev) { | 197 | if (!input_dev) { |
196 | printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); | 198 | printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); |
197 | error = -ENOMEM; | 199 | return -ENOMEM; |
198 | goto out1; | ||
199 | } | 200 | } |
200 | 201 | ||
201 | snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), | 202 | snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), |
@@ -217,6 +218,11 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
217 | } | 218 | } |
218 | input_dev->dev.parent = &saa->pci->dev; | 219 | input_dev->dev.parent = &saa->pci->dev; |
219 | 220 | ||
221 | if (rc5_device < 0) | ||
222 | budget_ci->ir.rc5_device = IR_DEVICE_ANY; | ||
223 | else | ||
224 | budget_ci->ir.rc5_device = rc5_device; | ||
225 | |||
220 | /* Select keymap and address */ | 226 | /* Select keymap and address */ |
221 | switch (budget_ci->budget.dev->pci->subsystem_device) { | 227 | switch (budget_ci->budget.dev->pci->subsystem_device) { |
222 | case 0x100c: | 228 | case 0x100c: |
@@ -224,53 +230,34 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
224 | case 0x1011: | 230 | case 0x1011: |
225 | case 0x1012: | 231 | case 0x1012: |
226 | /* The hauppauge keymap is a superset of these remotes */ | 232 | /* The hauppauge keymap is a superset of these remotes */ |
227 | error = ir_input_init(input_dev, &budget_ci->ir.state, | 233 | ir_codes = &ir_codes_hauppauge_new_table; |
228 | IR_TYPE_RC5, &ir_codes_hauppauge_new_table); | ||
229 | if (error < 0) | ||
230 | goto out2; | ||
231 | 234 | ||
232 | if (rc5_device < 0) | 235 | if (rc5_device < 0) |
233 | budget_ci->ir.rc5_device = 0x1f; | 236 | budget_ci->ir.rc5_device = 0x1f; |
234 | else | ||
235 | budget_ci->ir.rc5_device = rc5_device; | ||
236 | break; | 237 | break; |
237 | case 0x1010: | 238 | case 0x1010: |
238 | case 0x1017: | 239 | case 0x1017: |
239 | case 0x101a: | 240 | case 0x101a: |
240 | /* for the Technotrend 1500 bundled remote */ | 241 | /* for the Technotrend 1500 bundled remote */ |
241 | error = ir_input_init(input_dev, &budget_ci->ir.state, | 242 | ir_codes = &ir_codes_tt_1500_table; |
242 | IR_TYPE_RC5, &ir_codes_tt_1500_table); | ||
243 | if (error < 0) | ||
244 | goto out2; | ||
245 | |||
246 | if (rc5_device < 0) | ||
247 | budget_ci->ir.rc5_device = IR_DEVICE_ANY; | ||
248 | else | ||
249 | budget_ci->ir.rc5_device = rc5_device; | ||
250 | break; | 243 | break; |
251 | default: | 244 | default: |
252 | /* unknown remote */ | 245 | /* unknown remote */ |
253 | error = ir_input_init(input_dev, &budget_ci->ir.state, | 246 | ir_codes = &ir_codes_budget_ci_old_table; |
254 | IR_TYPE_RC5, &ir_codes_budget_ci_old_table); | ||
255 | if (error < 0) | ||
256 | goto out2; | ||
257 | |||
258 | if (rc5_device < 0) | ||
259 | budget_ci->ir.rc5_device = IR_DEVICE_ANY; | ||
260 | else | ||
261 | budget_ci->ir.rc5_device = rc5_device; | ||
262 | break; | 247 | break; |
263 | } | 248 | } |
264 | 249 | ||
250 | ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5); | ||
251 | |||
265 | /* initialise the key-up timeout handler */ | 252 | /* initialise the key-up timeout handler */ |
266 | init_timer(&budget_ci->ir.timer_keyup); | 253 | init_timer(&budget_ci->ir.timer_keyup); |
267 | budget_ci->ir.timer_keyup.function = msp430_ir_keyup; | 254 | budget_ci->ir.timer_keyup.function = msp430_ir_keyup; |
268 | budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir; | 255 | budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir; |
269 | budget_ci->ir.last_raw = 0xffff; /* An impossible value */ | 256 | budget_ci->ir.last_raw = 0xffff; /* An impossible value */ |
270 | error = input_register_device(input_dev); | 257 | error = ir_input_register(input_dev, ir_codes); |
271 | if (error) { | 258 | if (error) { |
272 | printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); | 259 | printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); |
273 | goto out2; | 260 | return error; |
274 | } | 261 | } |
275 | 262 | ||
276 | /* note: these must be after input_register_device */ | 263 | /* note: these must be after input_register_device */ |
@@ -284,12 +271,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
284 | saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); | 271 | saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); |
285 | 272 | ||
286 | return 0; | 273 | return 0; |
287 | |||
288 | out2: | ||
289 | ir_input_free(input_dev); | ||
290 | input_free_device(input_dev); | ||
291 | out1: | ||
292 | return error; | ||
293 | } | 274 | } |
294 | 275 | ||
295 | static void msp430_ir_deinit(struct budget_ci *budget_ci) | 276 | static void msp430_ir_deinit(struct budget_ci *budget_ci) |
@@ -304,8 +285,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) | |||
304 | del_timer_sync(&dev->timer); | 285 | del_timer_sync(&dev->timer); |
305 | ir_input_nokey(dev, &budget_ci->ir.state); | 286 | ir_input_nokey(dev, &budget_ci->ir.state); |
306 | 287 | ||
307 | ir_input_free(dev); | 288 | ir_input_unregister(dev); |
308 | input_unregister_device(dev); | ||
309 | } | 289 | } |
310 | 290 | ||
311 | static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) | 291 | static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 4c2b8a24677..3f40f375981 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -215,13 +215,10 @@ config RADIO_MIROPCM20 | |||
215 | module will be called radio-miropcm20. | 215 | module will be called radio-miropcm20. |
216 | 216 | ||
217 | config RADIO_SF16FMI | 217 | config RADIO_SF16FMI |
218 | tristate "SF16FMI Radio" | 218 | tristate "SF16-FMI/SF16-FMP Radio" |
219 | depends on ISA && VIDEO_V4L2 | 219 | depends on ISA && VIDEO_V4L2 |
220 | ---help--- | 220 | ---help--- |
221 | Choose Y here if you have one of these FM radio cards. If you | 221 | Choose Y here if you have one of these FM radio cards. |
222 | compile the driver into the kernel and your card is not PnP one, you | ||
223 | have to add "sf16fm=<io>" to the kernel command line (I/O address is | ||
224 | 0x284 or 0x384). | ||
225 | 222 | ||
226 | In order to control your radio card, you will need to use programs | 223 | In order to control your radio card, you will need to use programs |
227 | that are compatible with the Video For Linux API. Information on | 224 | that are compatible with the Video For Linux API. Information on |
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 35edee009ba..5bf4985daed 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
@@ -268,6 +268,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
268 | { | 268 | { |
269 | struct rtrack *rt = video_drvdata(file); | 269 | struct rtrack *rt = video_drvdata(file); |
270 | 270 | ||
271 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
272 | return -EINVAL; | ||
271 | rt_setfreq(rt, f->frequency); | 273 | rt_setfreq(rt, f->frequency); |
272 | return 0; | 274 | return 0; |
273 | } | 275 | } |
@@ -277,6 +279,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
277 | { | 279 | { |
278 | struct rtrack *rt = video_drvdata(file); | 280 | struct rtrack *rt = video_drvdata(file); |
279 | 281 | ||
282 | if (f->tuner != 0) | ||
283 | return -EINVAL; | ||
280 | f->type = V4L2_TUNER_RADIO; | 284 | f->type = V4L2_TUNER_RADIO; |
281 | f->frequency = rt->curfreq; | 285 | f->frequency = rt->curfreq; |
282 | return 0; | 286 | return 0; |
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 8daf809eb01..c2231139362 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
@@ -254,6 +254,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
254 | { | 254 | { |
255 | struct aztech *az = video_drvdata(file); | 255 | struct aztech *az = video_drvdata(file); |
256 | 256 | ||
257 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
258 | return -EINVAL; | ||
257 | az_setfreq(az, f->frequency); | 259 | az_setfreq(az, f->frequency); |
258 | return 0; | 260 | return 0; |
259 | } | 261 | } |
@@ -263,6 +265,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
263 | { | 265 | { |
264 | struct aztech *az = video_drvdata(file); | 266 | struct aztech *az = video_drvdata(file); |
265 | 267 | ||
268 | if (f->tuner != 0) | ||
269 | return -EINVAL; | ||
266 | f->type = V4L2_TUNER_RADIO; | 270 | f->type = V4L2_TUNER_RADIO; |
267 | f->frequency = az->curfreq; | 271 | f->frequency = az->curfreq; |
268 | return 0; | 272 | return 0; |
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index c6cf1166186..000f4d34087 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
@@ -240,6 +240,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
240 | { | 240 | { |
241 | struct gemtek_pci *card = video_drvdata(file); | 241 | struct gemtek_pci *card = video_drvdata(file); |
242 | 242 | ||
243 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
244 | return -EINVAL; | ||
243 | if (f->frequency < GEMTEK_PCI_RANGE_LOW || | 245 | if (f->frequency < GEMTEK_PCI_RANGE_LOW || |
244 | f->frequency > GEMTEK_PCI_RANGE_HIGH) | 246 | f->frequency > GEMTEK_PCI_RANGE_HIGH) |
245 | return -EINVAL; | 247 | return -EINVAL; |
@@ -253,6 +255,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
253 | { | 255 | { |
254 | struct gemtek_pci *card = video_drvdata(file); | 256 | struct gemtek_pci *card = video_drvdata(file); |
255 | 257 | ||
258 | if (f->tuner != 0) | ||
259 | return -EINVAL; | ||
256 | f->type = V4L2_TUNER_RADIO; | 260 | f->type = V4L2_TUNER_RADIO; |
257 | f->frequency = card->current_frequency; | 261 | f->frequency = card->current_frequency; |
258 | return 0; | 262 | return 0; |
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 64d737c35ac..f8213b7c8dd 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
@@ -200,6 +200,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
200 | { | 200 | { |
201 | struct maestro *dev = video_drvdata(file); | 201 | struct maestro *dev = video_drvdata(file); |
202 | 202 | ||
203 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
204 | return -EINVAL; | ||
203 | if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) | 205 | if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) |
204 | return -EINVAL; | 206 | return -EINVAL; |
205 | mutex_lock(&dev->lock); | 207 | mutex_lock(&dev->lock); |
@@ -213,6 +215,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
213 | { | 215 | { |
214 | struct maestro *dev = video_drvdata(file); | 216 | struct maestro *dev = video_drvdata(file); |
215 | 217 | ||
218 | if (f->tuner != 0) | ||
219 | return -EINVAL; | ||
216 | f->type = V4L2_TUNER_RADIO; | 220 | f->type = V4L2_TUNER_RADIO; |
217 | mutex_lock(&dev->lock); | 221 | mutex_lock(&dev->lock); |
218 | f->frequency = BITS2FREQ(radio_bits_get(dev)); | 222 | f->frequency = BITS2FREQ(radio_bits_get(dev)); |
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 3da51fe8fb9..44b4dbedb32 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
@@ -262,6 +262,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
262 | { | 262 | { |
263 | struct maxiradio *dev = video_drvdata(file); | 263 | struct maxiradio *dev = video_drvdata(file); |
264 | 264 | ||
265 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
266 | return -EINVAL; | ||
265 | if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) { | 267 | if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) { |
266 | dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n", | 268 | dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n", |
267 | f->frequency / 16000, | 269 | f->frequency / 16000, |
@@ -285,6 +287,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
285 | { | 287 | { |
286 | struct maxiradio *dev = video_drvdata(file); | 288 | struct maxiradio *dev = video_drvdata(file); |
287 | 289 | ||
290 | if (f->tuner != 0) | ||
291 | return -EINVAL; | ||
288 | f->type = V4L2_TUNER_RADIO; | 292 | f->type = V4L2_TUNER_RADIO; |
289 | f->frequency = dev->freq; | 293 | f->frequency = dev->freq; |
290 | 294 | ||
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 949f60513d9..02a9cefc9a0 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -374,6 +374,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
374 | { | 374 | { |
375 | struct amradio_device *radio = file->private_data; | 375 | struct amradio_device *radio = file->private_data; |
376 | 376 | ||
377 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
378 | return -EINVAL; | ||
377 | return amradio_setfreq(radio, f->frequency); | 379 | return amradio_setfreq(radio, f->frequency); |
378 | } | 380 | } |
379 | 381 | ||
@@ -383,6 +385,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
383 | { | 385 | { |
384 | struct amradio_device *radio = file->private_data; | 386 | struct amradio_device *radio = file->private_data; |
385 | 387 | ||
388 | if (f->tuner != 0) | ||
389 | return -EINVAL; | ||
386 | f->type = V4L2_TUNER_RADIO; | 390 | f->type = V4L2_TUNER_RADIO; |
387 | f->frequency = radio->curfreq; | 391 | f->frequency = radio->curfreq; |
388 | 392 | ||
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 9cb193fa6e3..a79296aac9a 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
@@ -167,6 +167,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
167 | { | 167 | { |
168 | struct rtrack2 *rt = video_drvdata(file); | 168 | struct rtrack2 *rt = video_drvdata(file); |
169 | 169 | ||
170 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
171 | return -EINVAL; | ||
170 | rt_setfreq(rt, f->frequency); | 172 | rt_setfreq(rt, f->frequency); |
171 | return 0; | 173 | return 0; |
172 | } | 174 | } |
@@ -176,6 +178,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
176 | { | 178 | { |
177 | struct rtrack2 *rt = video_drvdata(file); | 179 | struct rtrack2 *rt = video_drvdata(file); |
178 | 180 | ||
181 | if (f->tuner != 0) | ||
182 | return -EINVAL; | ||
179 | f->type = V4L2_TUNER_RADIO; | 183 | f->type = V4L2_TUNER_RADIO; |
180 | f->frequency = rt->curfreq; | 184 | f->frequency = rt->curfreq; |
181 | return 0; | 185 | return 0; |
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 49c4aab95da..985359d18aa 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* SF16FMI radio driver for Linux radio support | 1 | /* SF16-FMI and SF16-FMP radio driver for Linux radio support |
2 | * heavily based on rtrack driver... | 2 | * heavily based on rtrack driver... |
3 | * (c) 1997 M. Kirkwood | 3 | * (c) 1997 M. Kirkwood |
4 | * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz | 4 | * (c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz |
@@ -11,7 +11,7 @@ | |||
11 | * | 11 | * |
12 | * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); | 12 | * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); |
13 | * No volume control - only mute/unmute - you have to use line volume | 13 | * No volume control - only mute/unmute - you have to use line volume |
14 | * control on SB-part of SF16FMI | 14 | * control on SB-part of SF16-FMI/SF16-FMP |
15 | * | 15 | * |
16 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | 16 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> |
17 | */ | 17 | */ |
@@ -30,14 +30,14 @@ | |||
30 | #include <media/v4l2-ioctl.h> | 30 | #include <media/v4l2-ioctl.h> |
31 | 31 | ||
32 | MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); | 32 | MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); |
33 | MODULE_DESCRIPTION("A driver for the SF16MI radio."); | 33 | MODULE_DESCRIPTION("A driver for the SF16-FMI and SF16-FMP radio."); |
34 | MODULE_LICENSE("GPL"); | 34 | MODULE_LICENSE("GPL"); |
35 | 35 | ||
36 | static int io = -1; | 36 | static int io = -1; |
37 | static int radio_nr = -1; | 37 | static int radio_nr = -1; |
38 | 38 | ||
39 | module_param(io, int, 0); | 39 | module_param(io, int, 0); |
40 | MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)"); | 40 | MODULE_PARM_DESC(io, "I/O address of the SF16-FMI or SF16-FMP card (0x284 or 0x384)"); |
41 | module_param(radio_nr, int, 0); | 41 | module_param(radio_nr, int, 0); |
42 | 42 | ||
43 | #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) | 43 | #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) |
@@ -47,13 +47,14 @@ struct fmi | |||
47 | struct v4l2_device v4l2_dev; | 47 | struct v4l2_device v4l2_dev; |
48 | struct video_device vdev; | 48 | struct video_device vdev; |
49 | int io; | 49 | int io; |
50 | int curvol; /* 1 or 0 */ | 50 | bool mute; |
51 | unsigned long curfreq; /* freq in kHz */ | 51 | unsigned long curfreq; /* freq in kHz */ |
52 | struct mutex lock; | 52 | struct mutex lock; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static struct fmi fmi_card; | 55 | static struct fmi fmi_card; |
56 | static struct pnp_dev *dev; | 56 | static struct pnp_dev *dev; |
57 | bool pnp_attached; | ||
57 | 58 | ||
58 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ | 59 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ |
59 | /* It is only useful to give freq in interval of 800 (=0.05Mhz), | 60 | /* It is only useful to give freq in interval of 800 (=0.05Mhz), |
@@ -105,7 +106,7 @@ static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq) | |||
105 | outbits(8, 0xC0, fmi->io); | 106 | outbits(8, 0xC0, fmi->io); |
106 | msleep(143); /* was schedule_timeout(HZ/7) */ | 107 | msleep(143); /* was schedule_timeout(HZ/7) */ |
107 | mutex_unlock(&fmi->lock); | 108 | mutex_unlock(&fmi->lock); |
108 | if (fmi->curvol) | 109 | if (!fmi->mute) |
109 | fmi_unmute(fmi); | 110 | fmi_unmute(fmi); |
110 | return 0; | 111 | return 0; |
111 | } | 112 | } |
@@ -116,7 +117,7 @@ static inline int fmi_getsigstr(struct fmi *fmi) | |||
116 | int res; | 117 | int res; |
117 | 118 | ||
118 | mutex_lock(&fmi->lock); | 119 | mutex_lock(&fmi->lock); |
119 | val = fmi->curvol ? 0x08 : 0x00; /* unmute/mute */ | 120 | val = fmi->mute ? 0x00 : 0x08; /* mute/unmute */ |
120 | outb(val, fmi->io); | 121 | outb(val, fmi->io); |
121 | outb(val | 0x10, fmi->io); | 122 | outb(val | 0x10, fmi->io); |
122 | msleep(143); /* was schedule_timeout(HZ/7) */ | 123 | msleep(143); /* was schedule_timeout(HZ/7) */ |
@@ -168,6 +169,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
168 | { | 169 | { |
169 | struct fmi *fmi = video_drvdata(file); | 170 | struct fmi *fmi = video_drvdata(file); |
170 | 171 | ||
172 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
173 | return -EINVAL; | ||
171 | if (f->frequency < RSF16_MINFREQ || | 174 | if (f->frequency < RSF16_MINFREQ || |
172 | f->frequency > RSF16_MAXFREQ) | 175 | f->frequency > RSF16_MAXFREQ) |
173 | return -EINVAL; | 176 | return -EINVAL; |
@@ -182,6 +185,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
182 | { | 185 | { |
183 | struct fmi *fmi = video_drvdata(file); | 186 | struct fmi *fmi = video_drvdata(file); |
184 | 187 | ||
188 | if (f->tuner != 0) | ||
189 | return -EINVAL; | ||
185 | f->type = V4L2_TUNER_RADIO; | 190 | f->type = V4L2_TUNER_RADIO; |
186 | f->frequency = fmi->curfreq; | 191 | f->frequency = fmi->curfreq; |
187 | return 0; | 192 | return 0; |
@@ -204,7 +209,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
204 | 209 | ||
205 | switch (ctrl->id) { | 210 | switch (ctrl->id) { |
206 | case V4L2_CID_AUDIO_MUTE: | 211 | case V4L2_CID_AUDIO_MUTE: |
207 | ctrl->value = fmi->curvol; | 212 | ctrl->value = fmi->mute; |
208 | return 0; | 213 | return 0; |
209 | } | 214 | } |
210 | return -EINVAL; | 215 | return -EINVAL; |
@@ -221,7 +226,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
221 | fmi_mute(fmi); | 226 | fmi_mute(fmi); |
222 | else | 227 | else |
223 | fmi_unmute(fmi); | 228 | fmi_unmute(fmi); |
224 | fmi->curvol = ctrl->value; | 229 | fmi->mute = ctrl->value; |
225 | return 0; | 230 | return 0; |
226 | } | 231 | } |
227 | return -EINVAL; | 232 | return -EINVAL; |
@@ -316,26 +321,54 @@ static int __init fmi_init(void) | |||
316 | { | 321 | { |
317 | struct fmi *fmi = &fmi_card; | 322 | struct fmi *fmi = &fmi_card; |
318 | struct v4l2_device *v4l2_dev = &fmi->v4l2_dev; | 323 | struct v4l2_device *v4l2_dev = &fmi->v4l2_dev; |
319 | int res; | 324 | int res, i; |
325 | int probe_ports[] = { 0, 0x284, 0x384 }; | ||
326 | |||
327 | if (io < 0) { | ||
328 | for (i = 0; i < ARRAY_SIZE(probe_ports); i++) { | ||
329 | io = probe_ports[i]; | ||
330 | if (io == 0) { | ||
331 | io = isapnp_fmi_probe(); | ||
332 | if (io < 0) | ||
333 | continue; | ||
334 | pnp_attached = 1; | ||
335 | } | ||
336 | if (!request_region(io, 2, "radio-sf16fmi")) { | ||
337 | if (pnp_attached) | ||
338 | pnp_device_detach(dev); | ||
339 | io = -1; | ||
340 | continue; | ||
341 | } | ||
342 | if (pnp_attached || | ||
343 | ((inb(io) & 0xf9) == 0xf9 && (inb(io) & 0x4) == 0)) | ||
344 | break; | ||
345 | release_region(io, 2); | ||
346 | io = -1; | ||
347 | } | ||
348 | } else { | ||
349 | if (!request_region(io, 2, "radio-sf16fmi")) { | ||
350 | printk(KERN_ERR "radio-sf16fmi: port %#x already in use\n", io); | ||
351 | return -EBUSY; | ||
352 | } | ||
353 | if (inb(io) == 0xff) { | ||
354 | printk(KERN_ERR "radio-sf16fmi: card not present at %#x\n", io); | ||
355 | release_region(io, 2); | ||
356 | return -ENODEV; | ||
357 | } | ||
358 | } | ||
359 | if (io < 0) { | ||
360 | printk(KERN_ERR "radio-sf16fmi: no cards found\n"); | ||
361 | return -ENODEV; | ||
362 | } | ||
320 | 363 | ||
321 | if (io < 0) | ||
322 | io = isapnp_fmi_probe(); | ||
323 | strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name)); | 364 | strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name)); |
324 | fmi->io = io; | 365 | fmi->io = io; |
325 | if (fmi->io < 0) { | ||
326 | v4l2_err(v4l2_dev, "No PnP card found.\n"); | ||
327 | return fmi->io; | ||
328 | } | ||
329 | if (!request_region(io, 2, "radio-sf16fmi")) { | ||
330 | v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io); | ||
331 | pnp_device_detach(dev); | ||
332 | return -EBUSY; | ||
333 | } | ||
334 | 366 | ||
335 | res = v4l2_device_register(NULL, v4l2_dev); | 367 | res = v4l2_device_register(NULL, v4l2_dev); |
336 | if (res < 0) { | 368 | if (res < 0) { |
337 | release_region(fmi->io, 2); | 369 | release_region(fmi->io, 2); |
338 | pnp_device_detach(dev); | 370 | if (pnp_attached) |
371 | pnp_device_detach(dev); | ||
339 | v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); | 372 | v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); |
340 | return res; | 373 | return res; |
341 | } | 374 | } |
@@ -352,7 +385,8 @@ static int __init fmi_init(void) | |||
352 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 385 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
353 | v4l2_device_unregister(v4l2_dev); | 386 | v4l2_device_unregister(v4l2_dev); |
354 | release_region(fmi->io, 2); | 387 | release_region(fmi->io, 2); |
355 | pnp_device_detach(dev); | 388 | if (pnp_attached) |
389 | pnp_device_detach(dev); | ||
356 | return -EINVAL; | 390 | return -EINVAL; |
357 | } | 391 | } |
358 | 392 | ||
@@ -369,7 +403,7 @@ static void __exit fmi_exit(void) | |||
369 | video_unregister_device(&fmi->vdev); | 403 | video_unregister_device(&fmi->vdev); |
370 | v4l2_device_unregister(&fmi->v4l2_dev); | 404 | v4l2_device_unregister(&fmi->v4l2_dev); |
371 | release_region(fmi->io, 2); | 405 | release_region(fmi->io, 2); |
372 | if (dev) | 406 | if (dev && pnp_attached) |
373 | pnp_device_detach(dev); | 407 | pnp_device_detach(dev); |
374 | } | 408 | } |
375 | 409 | ||
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index a11414f648d..52c7bbb32b8 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
@@ -251,6 +251,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
251 | { | 251 | { |
252 | struct fmr2 *fmr2 = video_drvdata(file); | 252 | struct fmr2 *fmr2 = video_drvdata(file); |
253 | 253 | ||
254 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
255 | return -EINVAL; | ||
254 | if (f->frequency < RSF16_MINFREQ || | 256 | if (f->frequency < RSF16_MINFREQ || |
255 | f->frequency > RSF16_MAXFREQ) | 257 | f->frequency > RSF16_MAXFREQ) |
256 | return -EINVAL; | 258 | return -EINVAL; |
@@ -272,6 +274,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
272 | { | 274 | { |
273 | struct fmr2 *fmr2 = video_drvdata(file); | 275 | struct fmr2 *fmr2 = video_drvdata(file); |
274 | 276 | ||
277 | if (f->tuner != 0) | ||
278 | return -EINVAL; | ||
275 | f->type = V4L2_TUNER_RADIO; | 279 | f->type = V4L2_TUNER_RADIO; |
276 | f->frequency = fmr2->curfreq; | 280 | f->frequency = fmr2->curfreq; |
277 | return 0; | 281 | return 0; |
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 3cd76dddb6a..8e718bfcdad 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c | |||
@@ -314,7 +314,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
314 | if (v->index > 0) | 314 | if (v->index > 0) |
315 | return -EINVAL; | 315 | return -EINVAL; |
316 | 316 | ||
317 | memset(v, 0, sizeof(v)); | 317 | memset(v, 0, sizeof(*v)); |
318 | strcpy(v->name, "FM"); | 318 | strcpy(v->name, "FM"); |
319 | v->type = V4L2_TUNER_RADIO; | 319 | v->type = V4L2_TUNER_RADIO; |
320 | tea5764_i2c_read(radio); | 320 | tea5764_i2c_read(radio); |
@@ -349,7 +349,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
349 | { | 349 | { |
350 | struct tea5764_device *radio = video_drvdata(file); | 350 | struct tea5764_device *radio = video_drvdata(file); |
351 | 351 | ||
352 | if (f->tuner != 0) | 352 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) |
353 | return -EINVAL; | 353 | return -EINVAL; |
354 | if (f->frequency == 0) { | 354 | if (f->frequency == 0) { |
355 | /* We special case this as a power down control. */ | 355 | /* We special case this as a power down control. */ |
@@ -370,8 +370,10 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
370 | struct tea5764_device *radio = video_drvdata(file); | 370 | struct tea5764_device *radio = video_drvdata(file); |
371 | struct tea5764_regs *r = &radio->regs; | 371 | struct tea5764_regs *r = &radio->regs; |
372 | 372 | ||
373 | if (f->tuner != 0) | ||
374 | return -EINVAL; | ||
373 | tea5764_i2c_read(radio); | 375 | tea5764_i2c_read(radio); |
374 | memset(f, 0, sizeof(f)); | 376 | memset(f, 0, sizeof(*f)); |
375 | f->type = V4L2_TUNER_RADIO; | 377 | f->type = V4L2_TUNER_RADIO; |
376 | if (r->tnctrl & TEA5764_TNCTRL_PUPD0) | 378 | if (r->tnctrl & TEA5764_TNCTRL_PUPD0) |
377 | f->frequency = (tea5764_get_freq(radio) * 2) / 125; | 379 | f->frequency = (tea5764_get_freq(radio) * 2) / 125; |
@@ -458,12 +460,8 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
458 | static int tea5764_open(struct file *file) | 460 | static int tea5764_open(struct file *file) |
459 | { | 461 | { |
460 | /* Currently we support only one device */ | 462 | /* Currently we support only one device */ |
461 | int minor = video_devdata(file)->minor; | ||
462 | struct tea5764_device *radio = video_drvdata(file); | 463 | struct tea5764_device *radio = video_drvdata(file); |
463 | 464 | ||
464 | if (radio->videodev->minor != minor) | ||
465 | return -ENODEV; | ||
466 | |||
467 | mutex_lock(&radio->mutex); | 465 | mutex_lock(&radio->mutex); |
468 | /* Only exclusive access */ | 466 | /* Only exclusive access */ |
469 | if (radio->users) { | 467 | if (radio->users) { |
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index 699db9acaaf..fc1c860fd43 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
@@ -240,6 +240,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
240 | { | 240 | { |
241 | struct terratec *tt = video_drvdata(file); | 241 | struct terratec *tt = video_drvdata(file); |
242 | 242 | ||
243 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
244 | return -EINVAL; | ||
243 | tt_setfreq(tt, f->frequency); | 245 | tt_setfreq(tt, f->frequency); |
244 | return 0; | 246 | return 0; |
245 | } | 247 | } |
@@ -249,6 +251,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
249 | { | 251 | { |
250 | struct terratec *tt = video_drvdata(file); | 252 | struct terratec *tt = video_drvdata(file); |
251 | 253 | ||
254 | if (f->tuner != 0) | ||
255 | return -EINVAL; | ||
252 | f->type = V4L2_TUNER_RADIO; | 256 | f->type = V4L2_TUNER_RADIO; |
253 | f->frequency = tt->curfreq; | 257 | f->frequency = tt->curfreq; |
254 | return 0; | 258 | return 0; |
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 6f9ecc35935..9d6dcf8af5b 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
@@ -239,6 +239,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
239 | { | 239 | { |
240 | struct trust *tr = video_drvdata(file); | 240 | struct trust *tr = video_drvdata(file); |
241 | 241 | ||
242 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
243 | return -EINVAL; | ||
242 | tr_setfreq(tr, f->frequency); | 244 | tr_setfreq(tr, f->frequency); |
243 | return 0; | 245 | return 0; |
244 | } | 246 | } |
@@ -248,6 +250,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
248 | { | 250 | { |
249 | struct trust *tr = video_drvdata(file); | 251 | struct trust *tr = video_drvdata(file); |
250 | 252 | ||
253 | if (f->tuner != 0) | ||
254 | return -EINVAL; | ||
251 | f->type = V4L2_TUNER_RADIO; | 255 | f->type = V4L2_TUNER_RADIO; |
252 | f->frequency = tr->curfreq; | 256 | f->frequency = tr->curfreq; |
253 | return 0; | 257 | return 0; |
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 3a98f139949..03439282dfc 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
@@ -207,6 +207,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
207 | { | 207 | { |
208 | struct typhoon *dev = video_drvdata(file); | 208 | struct typhoon *dev = video_drvdata(file); |
209 | 209 | ||
210 | if (f->tuner != 0) | ||
211 | return -EINVAL; | ||
210 | f->type = V4L2_TUNER_RADIO; | 212 | f->type = V4L2_TUNER_RADIO; |
211 | f->frequency = dev->curfreq; | 213 | f->frequency = dev->curfreq; |
212 | return 0; | 214 | return 0; |
@@ -217,6 +219,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
217 | { | 219 | { |
218 | struct typhoon *dev = video_drvdata(file); | 220 | struct typhoon *dev = video_drvdata(file); |
219 | 221 | ||
222 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
223 | return -EINVAL; | ||
220 | dev->curfreq = f->frequency; | 224 | dev->curfreq = f->frequency; |
221 | typhoon_setfreq(dev, dev->curfreq); | 225 | typhoon_setfreq(dev, dev->curfreq); |
222 | return 0; | 226 | return 0; |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 80e98b6422f..f31eab99c94 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
@@ -266,6 +266,8 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
266 | { | 266 | { |
267 | struct zoltrix *zol = video_drvdata(file); | 267 | struct zoltrix *zol = video_drvdata(file); |
268 | 268 | ||
269 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
270 | return -EINVAL; | ||
269 | if (zol_setfreq(zol, f->frequency) != 0) | 271 | if (zol_setfreq(zol, f->frequency) != 0) |
270 | return -EINVAL; | 272 | return -EINVAL; |
271 | return 0; | 273 | return 0; |
@@ -276,6 +278,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
276 | { | 278 | { |
277 | struct zoltrix *zol = video_drvdata(file); | 279 | struct zoltrix *zol = video_drvdata(file); |
278 | 280 | ||
281 | if (f->tuner != 0) | ||
282 | return -EINVAL; | ||
279 | f->type = V4L2_TUNER_RADIO; | 283 | f->type = V4L2_TUNER_RADIO; |
280 | f->frequency = zol->curfreq; | 284 | f->frequency = zol->curfreq; |
281 | return 0; | 285 | return 0; |
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index f33315f2c54..4da0f150c6e 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -426,6 +426,104 @@ int si470x_rds_on(struct si470x_device *radio) | |||
426 | 426 | ||
427 | 427 | ||
428 | /************************************************************************** | 428 | /************************************************************************** |
429 | * File Operations Interface | ||
430 | **************************************************************************/ | ||
431 | |||
432 | /* | ||
433 | * si470x_fops_read - read RDS data | ||
434 | */ | ||
435 | static ssize_t si470x_fops_read(struct file *file, char __user *buf, | ||
436 | size_t count, loff_t *ppos) | ||
437 | { | ||
438 | struct si470x_device *radio = video_drvdata(file); | ||
439 | int retval = 0; | ||
440 | unsigned int block_count = 0; | ||
441 | |||
442 | /* switch on rds reception */ | ||
443 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | ||
444 | si470x_rds_on(radio); | ||
445 | |||
446 | /* block if no new data available */ | ||
447 | while (radio->wr_index == radio->rd_index) { | ||
448 | if (file->f_flags & O_NONBLOCK) { | ||
449 | retval = -EWOULDBLOCK; | ||
450 | goto done; | ||
451 | } | ||
452 | if (wait_event_interruptible(radio->read_queue, | ||
453 | radio->wr_index != radio->rd_index) < 0) { | ||
454 | retval = -EINTR; | ||
455 | goto done; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | /* calculate block count from byte count */ | ||
460 | count /= 3; | ||
461 | |||
462 | /* copy RDS block out of internal buffer and to user buffer */ | ||
463 | mutex_lock(&radio->lock); | ||
464 | while (block_count < count) { | ||
465 | if (radio->rd_index == radio->wr_index) | ||
466 | break; | ||
467 | |||
468 | /* always transfer rds complete blocks */ | ||
469 | if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3)) | ||
470 | /* retval = -EFAULT; */ | ||
471 | break; | ||
472 | |||
473 | /* increment and wrap read pointer */ | ||
474 | radio->rd_index += 3; | ||
475 | if (radio->rd_index >= radio->buf_size) | ||
476 | radio->rd_index = 0; | ||
477 | |||
478 | /* increment counters */ | ||
479 | block_count++; | ||
480 | buf += 3; | ||
481 | retval += 3; | ||
482 | } | ||
483 | mutex_unlock(&radio->lock); | ||
484 | |||
485 | done: | ||
486 | return retval; | ||
487 | } | ||
488 | |||
489 | |||
490 | /* | ||
491 | * si470x_fops_poll - poll RDS data | ||
492 | */ | ||
493 | static unsigned int si470x_fops_poll(struct file *file, | ||
494 | struct poll_table_struct *pts) | ||
495 | { | ||
496 | struct si470x_device *radio = video_drvdata(file); | ||
497 | int retval = 0; | ||
498 | |||
499 | /* switch on rds reception */ | ||
500 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | ||
501 | si470x_rds_on(radio); | ||
502 | |||
503 | poll_wait(file, &radio->read_queue, pts); | ||
504 | |||
505 | if (radio->rd_index != radio->wr_index) | ||
506 | retval = POLLIN | POLLRDNORM; | ||
507 | |||
508 | return retval; | ||
509 | } | ||
510 | |||
511 | |||
512 | /* | ||
513 | * si470x_fops - file operations interface | ||
514 | */ | ||
515 | static const struct v4l2_file_operations si470x_fops = { | ||
516 | .owner = THIS_MODULE, | ||
517 | .read = si470x_fops_read, | ||
518 | .poll = si470x_fops_poll, | ||
519 | .ioctl = video_ioctl2, | ||
520 | .open = si470x_fops_open, | ||
521 | .release = si470x_fops_release, | ||
522 | }; | ||
523 | |||
524 | |||
525 | |||
526 | /************************************************************************** | ||
429 | * Video4Linux Interface | 527 | * Video4Linux Interface |
430 | **************************************************************************/ | 528 | **************************************************************************/ |
431 | 529 | ||
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 2d53b6a9409..5466015346a 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c | |||
@@ -22,22 +22,17 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | 24 | ||
25 | /* | ||
26 | * ToDo: | ||
27 | * - RDS support | ||
28 | */ | ||
29 | |||
30 | |||
31 | /* driver definitions */ | 25 | /* driver definitions */ |
32 | #define DRIVER_AUTHOR "Joonyoung Shim <jy0922.shim@samsung.com>"; | 26 | #define DRIVER_AUTHOR "Joonyoung Shim <jy0922.shim@samsung.com>"; |
33 | #define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 0) | 27 | #define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 1) |
34 | #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" | 28 | #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" |
35 | #define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers" | 29 | #define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers" |
36 | #define DRIVER_VERSION "1.0.0" | 30 | #define DRIVER_VERSION "1.0.1" |
37 | 31 | ||
38 | /* kernel includes */ | 32 | /* kernel includes */ |
39 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
40 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | #include <linux/interrupt.h> | ||
41 | 36 | ||
42 | #include "radio-si470x.h" | 37 | #include "radio-si470x.h" |
43 | 38 | ||
@@ -62,6 +57,20 @@ static int radio_nr = -1; | |||
62 | module_param(radio_nr, int, 0444); | 57 | module_param(radio_nr, int, 0444); |
63 | MODULE_PARM_DESC(radio_nr, "Radio Nr"); | 58 | MODULE_PARM_DESC(radio_nr, "Radio Nr"); |
64 | 59 | ||
60 | /* RDS buffer blocks */ | ||
61 | static unsigned int rds_buf = 100; | ||
62 | module_param(rds_buf, uint, 0444); | ||
63 | MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); | ||
64 | |||
65 | /* RDS maximum block errors */ | ||
66 | static unsigned short max_rds_errors = 1; | ||
67 | /* 0 means 0 errors requiring correction */ | ||
68 | /* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */ | ||
69 | /* 2 means 3-5 errors requiring correction */ | ||
70 | /* 3 means 6+ errors or errors in checkword, correction not possible */ | ||
71 | module_param(max_rds_errors, ushort, 0644); | ||
72 | MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); | ||
73 | |||
65 | 74 | ||
66 | 75 | ||
67 | /************************************************************************** | 76 | /************************************************************************** |
@@ -173,7 +182,7 @@ int si470x_disconnect_check(struct si470x_device *radio) | |||
173 | /* | 182 | /* |
174 | * si470x_fops_open - file open | 183 | * si470x_fops_open - file open |
175 | */ | 184 | */ |
176 | static int si470x_fops_open(struct file *file) | 185 | int si470x_fops_open(struct file *file) |
177 | { | 186 | { |
178 | struct si470x_device *radio = video_drvdata(file); | 187 | struct si470x_device *radio = video_drvdata(file); |
179 | int retval = 0; | 188 | int retval = 0; |
@@ -181,12 +190,21 @@ static int si470x_fops_open(struct file *file) | |||
181 | mutex_lock(&radio->lock); | 190 | mutex_lock(&radio->lock); |
182 | radio->users++; | 191 | radio->users++; |
183 | 192 | ||
184 | if (radio->users == 1) | 193 | if (radio->users == 1) { |
185 | /* start radio */ | 194 | /* start radio */ |
186 | retval = si470x_start(radio); | 195 | retval = si470x_start(radio); |
196 | if (retval < 0) | ||
197 | goto done; | ||
198 | |||
199 | /* enable RDS interrupt */ | ||
200 | radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN; | ||
201 | radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2; | ||
202 | radio->registers[SYSCONFIG1] |= 0x1 << 2; | ||
203 | retval = si470x_set_register(radio, SYSCONFIG1); | ||
204 | } | ||
187 | 205 | ||
206 | done: | ||
188 | mutex_unlock(&radio->lock); | 207 | mutex_unlock(&radio->lock); |
189 | |||
190 | return retval; | 208 | return retval; |
191 | } | 209 | } |
192 | 210 | ||
@@ -194,7 +212,7 @@ static int si470x_fops_open(struct file *file) | |||
194 | /* | 212 | /* |
195 | * si470x_fops_release - file release | 213 | * si470x_fops_release - file release |
196 | */ | 214 | */ |
197 | static int si470x_fops_release(struct file *file) | 215 | int si470x_fops_release(struct file *file) |
198 | { | 216 | { |
199 | struct si470x_device *radio = video_drvdata(file); | 217 | struct si470x_device *radio = video_drvdata(file); |
200 | int retval = 0; | 218 | int retval = 0; |
@@ -215,17 +233,6 @@ static int si470x_fops_release(struct file *file) | |||
215 | } | 233 | } |
216 | 234 | ||
217 | 235 | ||
218 | /* | ||
219 | * si470x_fops - file operations interface | ||
220 | */ | ||
221 | const struct v4l2_file_operations si470x_fops = { | ||
222 | .owner = THIS_MODULE, | ||
223 | .ioctl = video_ioctl2, | ||
224 | .open = si470x_fops_open, | ||
225 | .release = si470x_fops_release, | ||
226 | }; | ||
227 | |||
228 | |||
229 | 236 | ||
230 | /************************************************************************** | 237 | /************************************************************************** |
231 | * Video4Linux Interface | 238 | * Video4Linux Interface |
@@ -253,6 +260,105 @@ int si470x_vidioc_querycap(struct file *file, void *priv, | |||
253 | **************************************************************************/ | 260 | **************************************************************************/ |
254 | 261 | ||
255 | /* | 262 | /* |
263 | * si470x_i2c_interrupt_work - rds processing function | ||
264 | */ | ||
265 | static void si470x_i2c_interrupt_work(struct work_struct *work) | ||
266 | { | ||
267 | struct si470x_device *radio = container_of(work, | ||
268 | struct si470x_device, radio_work); | ||
269 | unsigned char regnr; | ||
270 | unsigned char blocknum; | ||
271 | unsigned short bler; /* rds block errors */ | ||
272 | unsigned short rds; | ||
273 | unsigned char tmpbuf[3]; | ||
274 | int retval = 0; | ||
275 | |||
276 | /* safety checks */ | ||
277 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | ||
278 | return; | ||
279 | |||
280 | /* Update RDS registers */ | ||
281 | for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) { | ||
282 | retval = si470x_get_register(radio, STATUSRSSI + regnr); | ||
283 | if (retval < 0) | ||
284 | return; | ||
285 | } | ||
286 | |||
287 | /* get rds blocks */ | ||
288 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) | ||
289 | /* No RDS group ready, better luck next time */ | ||
290 | return; | ||
291 | |||
292 | for (blocknum = 0; blocknum < 4; blocknum++) { | ||
293 | switch (blocknum) { | ||
294 | default: | ||
295 | bler = (radio->registers[STATUSRSSI] & | ||
296 | STATUSRSSI_BLERA) >> 9; | ||
297 | rds = radio->registers[RDSA]; | ||
298 | break; | ||
299 | case 1: | ||
300 | bler = (radio->registers[READCHAN] & | ||
301 | READCHAN_BLERB) >> 14; | ||
302 | rds = radio->registers[RDSB]; | ||
303 | break; | ||
304 | case 2: | ||
305 | bler = (radio->registers[READCHAN] & | ||
306 | READCHAN_BLERC) >> 12; | ||
307 | rds = radio->registers[RDSC]; | ||
308 | break; | ||
309 | case 3: | ||
310 | bler = (radio->registers[READCHAN] & | ||
311 | READCHAN_BLERD) >> 10; | ||
312 | rds = radio->registers[RDSD]; | ||
313 | break; | ||
314 | }; | ||
315 | |||
316 | /* Fill the V4L2 RDS buffer */ | ||
317 | put_unaligned_le16(rds, &tmpbuf); | ||
318 | tmpbuf[2] = blocknum; /* offset name */ | ||
319 | tmpbuf[2] |= blocknum << 3; /* received offset */ | ||
320 | if (bler > max_rds_errors) | ||
321 | tmpbuf[2] |= 0x80; /* uncorrectable errors */ | ||
322 | else if (bler > 0) | ||
323 | tmpbuf[2] |= 0x40; /* corrected error(s) */ | ||
324 | |||
325 | /* copy RDS block to internal buffer */ | ||
326 | memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3); | ||
327 | radio->wr_index += 3; | ||
328 | |||
329 | /* wrap write pointer */ | ||
330 | if (radio->wr_index >= radio->buf_size) | ||
331 | radio->wr_index = 0; | ||
332 | |||
333 | /* check for overflow */ | ||
334 | if (radio->wr_index == radio->rd_index) { | ||
335 | /* increment and wrap read pointer */ | ||
336 | radio->rd_index += 3; | ||
337 | if (radio->rd_index >= radio->buf_size) | ||
338 | radio->rd_index = 0; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | if (radio->wr_index != radio->rd_index) | ||
343 | wake_up_interruptible(&radio->read_queue); | ||
344 | } | ||
345 | |||
346 | |||
347 | /* | ||
348 | * si470x_i2c_interrupt - interrupt handler | ||
349 | */ | ||
350 | static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id) | ||
351 | { | ||
352 | struct si470x_device *radio = dev_id; | ||
353 | |||
354 | if (!work_pending(&radio->radio_work)) | ||
355 | schedule_work(&radio->radio_work); | ||
356 | |||
357 | return IRQ_HANDLED; | ||
358 | } | ||
359 | |||
360 | |||
361 | /* | ||
256 | * si470x_i2c_probe - probe for the device | 362 | * si470x_i2c_probe - probe for the device |
257 | */ | 363 | */ |
258 | static int __devinit si470x_i2c_probe(struct i2c_client *client, | 364 | static int __devinit si470x_i2c_probe(struct i2c_client *client, |
@@ -268,6 +374,8 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, | |||
268 | retval = -ENOMEM; | 374 | retval = -ENOMEM; |
269 | goto err_initial; | 375 | goto err_initial; |
270 | } | 376 | } |
377 | |||
378 | INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work); | ||
271 | radio->users = 0; | 379 | radio->users = 0; |
272 | radio->client = client; | 380 | radio->client = client; |
273 | mutex_init(&radio->lock); | 381 | mutex_init(&radio->lock); |
@@ -319,6 +427,26 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, | |||
319 | /* set initial frequency */ | 427 | /* set initial frequency */ |
320 | si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ | 428 | si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ |
321 | 429 | ||
430 | /* rds buffer allocation */ | ||
431 | radio->buf_size = rds_buf * 3; | ||
432 | radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); | ||
433 | if (!radio->buffer) { | ||
434 | retval = -EIO; | ||
435 | goto err_video; | ||
436 | } | ||
437 | |||
438 | /* rds buffer configuration */ | ||
439 | radio->wr_index = 0; | ||
440 | radio->rd_index = 0; | ||
441 | init_waitqueue_head(&radio->read_queue); | ||
442 | |||
443 | retval = request_irq(client->irq, si470x_i2c_interrupt, | ||
444 | IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); | ||
445 | if (retval) { | ||
446 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
447 | goto err_rds; | ||
448 | } | ||
449 | |||
322 | /* register video device */ | 450 | /* register video device */ |
323 | retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, | 451 | retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, |
324 | radio_nr); | 452 | radio_nr); |
@@ -330,6 +458,9 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, | |||
330 | 458 | ||
331 | return 0; | 459 | return 0; |
332 | err_all: | 460 | err_all: |
461 | free_irq(client->irq, radio); | ||
462 | err_rds: | ||
463 | kfree(radio->buffer); | ||
333 | err_video: | 464 | err_video: |
334 | video_device_release(radio->videodev); | 465 | video_device_release(radio->videodev); |
335 | err_radio: | 466 | err_radio: |
@@ -346,6 +477,8 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client) | |||
346 | { | 477 | { |
347 | struct si470x_device *radio = i2c_get_clientdata(client); | 478 | struct si470x_device *radio = i2c_get_clientdata(client); |
348 | 479 | ||
480 | free_irq(client->irq, radio); | ||
481 | cancel_work_sync(&radio->radio_work); | ||
349 | video_unregister_device(radio->videodev); | 482 | video_unregister_device(radio->videodev); |
350 | kfree(radio); | 483 | kfree(radio); |
351 | i2c_set_clientdata(client, NULL); | 484 | i2c_set_clientdata(client, NULL); |
@@ -354,6 +487,44 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client) | |||
354 | } | 487 | } |
355 | 488 | ||
356 | 489 | ||
490 | #ifdef CONFIG_PM | ||
491 | /* | ||
492 | * si470x_i2c_suspend - suspend the device | ||
493 | */ | ||
494 | static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg) | ||
495 | { | ||
496 | struct si470x_device *radio = i2c_get_clientdata(client); | ||
497 | |||
498 | /* power down */ | ||
499 | radio->registers[POWERCFG] |= POWERCFG_DISABLE; | ||
500 | if (si470x_set_register(radio, POWERCFG) < 0) | ||
501 | return -EIO; | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | |||
507 | /* | ||
508 | * si470x_i2c_resume - resume the device | ||
509 | */ | ||
510 | static int si470x_i2c_resume(struct i2c_client *client) | ||
511 | { | ||
512 | struct si470x_device *radio = i2c_get_clientdata(client); | ||
513 | |||
514 | /* power up : need 110ms */ | ||
515 | radio->registers[POWERCFG] |= POWERCFG_ENABLE; | ||
516 | if (si470x_set_register(radio, POWERCFG) < 0) | ||
517 | return -EIO; | ||
518 | msleep(110); | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | #else | ||
523 | #define si470x_i2c_suspend NULL | ||
524 | #define si470x_i2c_resume NULL | ||
525 | #endif | ||
526 | |||
527 | |||
357 | /* | 528 | /* |
358 | * si470x_i2c_driver - i2c driver interface | 529 | * si470x_i2c_driver - i2c driver interface |
359 | */ | 530 | */ |
@@ -364,6 +535,8 @@ static struct i2c_driver si470x_i2c_driver = { | |||
364 | }, | 535 | }, |
365 | .probe = si470x_i2c_probe, | 536 | .probe = si470x_i2c_probe, |
366 | .remove = __devexit_p(si470x_i2c_remove), | 537 | .remove = __devexit_p(si470x_i2c_remove), |
538 | .suspend = si470x_i2c_suspend, | ||
539 | .resume = si470x_i2c_resume, | ||
367 | .id_table = si470x_i2c_id, | 540 | .id_table = si470x_i2c_id, |
368 | }; | 541 | }; |
369 | 542 | ||
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index f2d0e1ddb30..a96e1b9dd64 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c | |||
@@ -509,89 +509,9 @@ resubmit: | |||
509 | **************************************************************************/ | 509 | **************************************************************************/ |
510 | 510 | ||
511 | /* | 511 | /* |
512 | * si470x_fops_read - read RDS data | ||
513 | */ | ||
514 | static ssize_t si470x_fops_read(struct file *file, char __user *buf, | ||
515 | size_t count, loff_t *ppos) | ||
516 | { | ||
517 | struct si470x_device *radio = video_drvdata(file); | ||
518 | int retval = 0; | ||
519 | unsigned int block_count = 0; | ||
520 | |||
521 | /* switch on rds reception */ | ||
522 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | ||
523 | si470x_rds_on(radio); | ||
524 | |||
525 | /* block if no new data available */ | ||
526 | while (radio->wr_index == radio->rd_index) { | ||
527 | if (file->f_flags & O_NONBLOCK) { | ||
528 | retval = -EWOULDBLOCK; | ||
529 | goto done; | ||
530 | } | ||
531 | if (wait_event_interruptible(radio->read_queue, | ||
532 | radio->wr_index != radio->rd_index) < 0) { | ||
533 | retval = -EINTR; | ||
534 | goto done; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | /* calculate block count from byte count */ | ||
539 | count /= 3; | ||
540 | |||
541 | /* copy RDS block out of internal buffer and to user buffer */ | ||
542 | mutex_lock(&radio->lock); | ||
543 | while (block_count < count) { | ||
544 | if (radio->rd_index == radio->wr_index) | ||
545 | break; | ||
546 | |||
547 | /* always transfer rds complete blocks */ | ||
548 | if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3)) | ||
549 | /* retval = -EFAULT; */ | ||
550 | break; | ||
551 | |||
552 | /* increment and wrap read pointer */ | ||
553 | radio->rd_index += 3; | ||
554 | if (radio->rd_index >= radio->buf_size) | ||
555 | radio->rd_index = 0; | ||
556 | |||
557 | /* increment counters */ | ||
558 | block_count++; | ||
559 | buf += 3; | ||
560 | retval += 3; | ||
561 | } | ||
562 | mutex_unlock(&radio->lock); | ||
563 | |||
564 | done: | ||
565 | return retval; | ||
566 | } | ||
567 | |||
568 | |||
569 | /* | ||
570 | * si470x_fops_poll - poll RDS data | ||
571 | */ | ||
572 | static unsigned int si470x_fops_poll(struct file *file, | ||
573 | struct poll_table_struct *pts) | ||
574 | { | ||
575 | struct si470x_device *radio = video_drvdata(file); | ||
576 | int retval = 0; | ||
577 | |||
578 | /* switch on rds reception */ | ||
579 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | ||
580 | si470x_rds_on(radio); | ||
581 | |||
582 | poll_wait(file, &radio->read_queue, pts); | ||
583 | |||
584 | if (radio->rd_index != radio->wr_index) | ||
585 | retval = POLLIN | POLLRDNORM; | ||
586 | |||
587 | return retval; | ||
588 | } | ||
589 | |||
590 | |||
591 | /* | ||
592 | * si470x_fops_open - file open | 512 | * si470x_fops_open - file open |
593 | */ | 513 | */ |
594 | static int si470x_fops_open(struct file *file) | 514 | int si470x_fops_open(struct file *file) |
595 | { | 515 | { |
596 | struct si470x_device *radio = video_drvdata(file); | 516 | struct si470x_device *radio = video_drvdata(file); |
597 | int retval; | 517 | int retval; |
@@ -645,7 +565,7 @@ done: | |||
645 | /* | 565 | /* |
646 | * si470x_fops_release - file release | 566 | * si470x_fops_release - file release |
647 | */ | 567 | */ |
648 | static int si470x_fops_release(struct file *file) | 568 | int si470x_fops_release(struct file *file) |
649 | { | 569 | { |
650 | struct si470x_device *radio = video_drvdata(file); | 570 | struct si470x_device *radio = video_drvdata(file); |
651 | int retval = 0; | 571 | int retval = 0; |
@@ -688,19 +608,6 @@ done: | |||
688 | } | 608 | } |
689 | 609 | ||
690 | 610 | ||
691 | /* | ||
692 | * si470x_fops - file operations interface | ||
693 | */ | ||
694 | const struct v4l2_file_operations si470x_fops = { | ||
695 | .owner = THIS_MODULE, | ||
696 | .read = si470x_fops_read, | ||
697 | .poll = si470x_fops_poll, | ||
698 | .ioctl = video_ioctl2, | ||
699 | .open = si470x_fops_open, | ||
700 | .release = si470x_fops_release, | ||
701 | }; | ||
702 | |||
703 | |||
704 | 611 | ||
705 | /************************************************************************** | 612 | /************************************************************************** |
706 | * Video4Linux Interface | 613 | * Video4Linux Interface |
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index d0af194d194..3cd0a29cd6e 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/sched.h> | ||
32 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
33 | #include <linux/smp_lock.h> | 34 | #include <linux/smp_lock.h> |
34 | #include <linux/input.h> | 35 | #include <linux/input.h> |
@@ -181,6 +182,7 @@ struct si470x_device { | |||
181 | 182 | ||
182 | #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) | 183 | #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE) |
183 | struct i2c_client *client; | 184 | struct i2c_client *client; |
185 | struct work_struct radio_work; | ||
184 | #endif | 186 | #endif |
185 | }; | 187 | }; |
186 | 188 | ||
@@ -212,7 +214,6 @@ struct si470x_device { | |||
212 | /************************************************************************** | 214 | /************************************************************************** |
213 | * Common Functions | 215 | * Common Functions |
214 | **************************************************************************/ | 216 | **************************************************************************/ |
215 | extern const struct v4l2_file_operations si470x_fops; | ||
216 | extern struct video_device si470x_viddev_template; | 217 | extern struct video_device si470x_viddev_template; |
217 | int si470x_get_register(struct si470x_device *radio, int regnr); | 218 | int si470x_get_register(struct si470x_device *radio, int regnr); |
218 | int si470x_set_register(struct si470x_device *radio, int regnr); | 219 | int si470x_set_register(struct si470x_device *radio, int regnr); |
@@ -221,5 +222,7 @@ int si470x_set_freq(struct si470x_device *radio, unsigned int freq); | |||
221 | int si470x_start(struct si470x_device *radio); | 222 | int si470x_start(struct si470x_device *radio); |
222 | int si470x_stop(struct si470x_device *radio); | 223 | int si470x_stop(struct si470x_device *radio); |
223 | int si470x_rds_on(struct si470x_device *radio); | 224 | int si470x_rds_on(struct si470x_device *radio); |
225 | int si470x_fops_open(struct file *file); | ||
226 | int si470x_fops_release(struct file *file); | ||
224 | int si470x_vidioc_querycap(struct file *file, void *priv, | 227 | int si470x_vidioc_querycap(struct file *file, void *priv, |
225 | struct v4l2_capability *capability); | 228 | struct v4l2_capability *capability); |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 9dc74c93bf2..2f83be766d9 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -37,10 +37,6 @@ config VIDEO_BTCX | |||
37 | depends on PCI | 37 | depends on PCI |
38 | tristate | 38 | tristate |
39 | 39 | ||
40 | config VIDEO_IR | ||
41 | tristate | ||
42 | depends on INPUT | ||
43 | |||
44 | config VIDEO_TVEEPROM | 40 | config VIDEO_TVEEPROM |
45 | tristate | 41 | tristate |
46 | depends on I2C | 42 | depends on I2C |
@@ -840,6 +836,12 @@ config SOC_CAMERA_MT9T031 | |||
840 | help | 836 | help |
841 | This driver supports MT9T031 cameras from Micron. | 837 | This driver supports MT9T031 cameras from Micron. |
842 | 838 | ||
839 | config SOC_CAMERA_MT9T112 | ||
840 | tristate "mt9t112 support" | ||
841 | depends on SOC_CAMERA && I2C | ||
842 | help | ||
843 | This driver supports MT9T112 cameras from Aptina. | ||
844 | |||
843 | config SOC_CAMERA_MT9V022 | 845 | config SOC_CAMERA_MT9V022 |
844 | tristate "mt9v022 support" | 846 | tristate "mt9v022 support" |
845 | depends on SOC_CAMERA && I2C | 847 | depends on SOC_CAMERA && I2C |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 7a2dcc34111..2af68ee8412 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -75,6 +75,7 @@ obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o | |||
75 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o | 75 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o |
76 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o | 76 | obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o |
77 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | 77 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o |
78 | obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o | ||
78 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o | 79 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o |
79 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o | 80 | obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o |
80 | obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o | 81 | obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o |
@@ -149,7 +150,7 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o | |||
149 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ | 150 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ |
150 | 151 | ||
151 | obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o | 152 | obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o |
152 | obj-$(CONFIG_SOC_CAMERA) += soc_camera.o | 153 | obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o |
153 | obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o | 154 | obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o |
154 | # soc-camera host drivers have to be linked after camera drivers | 155 | # soc-camera host drivers have to be linked after camera drivers |
155 | obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o | 156 | obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o |
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index d137bac8451..a356d6bd313 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
@@ -767,7 +767,6 @@ static struct video_device ar_template = { | |||
767 | .name = "Colour AR VGA", | 767 | .name = "Colour AR VGA", |
768 | .fops = &ar_fops, | 768 | .fops = &ar_fops, |
769 | .release = ar_release, | 769 | .release = ar_release, |
770 | .minor = -1, | ||
771 | }; | 770 | }; |
772 | 771 | ||
773 | #define ALIGN4(x) ((((int)(x)) & 0x3) == 0) | 772 | #define ALIGN4(x) ((((int)(x)) & 0x3) == 0) |
@@ -860,8 +859,8 @@ static int __init ar_init(void) | |||
860 | goto out_dev; | 859 | goto out_dev; |
861 | } | 860 | } |
862 | 861 | ||
863 | printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", | 862 | printk("%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", |
864 | ar->vdev->num, M32R_IRQ_INT3, freq); | 863 | video_device_node_name(ar->vdev), M32R_IRQ_INT3, freq); |
865 | 864 | ||
866 | return 0; | 865 | return 0; |
867 | 866 | ||
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index 1485aee18d5..dc67bc40f36 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include "au0828.h" | 40 | #include "au0828.h" |
41 | #include "au0828-reg.h" | 41 | #include "au0828-reg.h" |
42 | 42 | ||
43 | static LIST_HEAD(au0828_devlist); | ||
44 | static DEFINE_MUTEX(au0828_sysfs_lock); | 43 | static DEFINE_MUTEX(au0828_sysfs_lock); |
45 | 44 | ||
46 | #define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1) | 45 | #define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1) |
@@ -693,10 +692,8 @@ void au0828_analog_unregister(struct au0828_dev *dev) | |||
693 | dprintk(1, "au0828_release_resources called\n"); | 692 | dprintk(1, "au0828_release_resources called\n"); |
694 | mutex_lock(&au0828_sysfs_lock); | 693 | mutex_lock(&au0828_sysfs_lock); |
695 | 694 | ||
696 | if (dev->vdev) { | 695 | if (dev->vdev) |
697 | list_del(&dev->au0828list); | ||
698 | video_unregister_device(dev->vdev); | 696 | video_unregister_device(dev->vdev); |
699 | } | ||
700 | if (dev->vbi_dev) | 697 | if (dev->vbi_dev) |
701 | video_unregister_device(dev->vbi_dev); | 698 | video_unregister_device(dev->vbi_dev); |
702 | 699 | ||
@@ -737,29 +734,15 @@ static void res_free(struct au0828_fh *fh) | |||
737 | 734 | ||
738 | static int au0828_v4l2_open(struct file *filp) | 735 | static int au0828_v4l2_open(struct file *filp) |
739 | { | 736 | { |
740 | int minor = video_devdata(filp)->minor; | ||
741 | int ret = 0; | 737 | int ret = 0; |
742 | struct au0828_dev *h, *dev = NULL; | 738 | struct au0828_dev *dev = video_drvdata(filp); |
743 | struct au0828_fh *fh; | 739 | struct au0828_fh *fh; |
744 | int type = 0; | 740 | int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
745 | struct list_head *list; | 741 | |
746 | |||
747 | list_for_each(list, &au0828_devlist) { | ||
748 | h = list_entry(list, struct au0828_dev, au0828list); | ||
749 | if (h->vdev->minor == minor) { | ||
750 | dev = h; | ||
751 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
752 | } | ||
753 | #ifdef VBI_IS_WORKING | 742 | #ifdef VBI_IS_WORKING |
754 | if (h->vbi_dev->minor == minor) { | 743 | if (video_devdata(filp)->vfl_type == VFL_TYPE_GRABBER) |
755 | dev = h; | 744 | type = V4L2_BUF_TYPE_VBI_CAPTURE; |
756 | type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
757 | } | ||
758 | #endif | 745 | #endif |
759 | } | ||
760 | |||
761 | if (NULL == dev) | ||
762 | return -ENODEV; | ||
763 | 746 | ||
764 | fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL); | 747 | fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL); |
765 | if (NULL == fh) { | 748 | if (NULL == fh) { |
@@ -1587,7 +1570,6 @@ static const struct video_device au0828_video_template = { | |||
1587 | .fops = &au0828_v4l_fops, | 1570 | .fops = &au0828_v4l_fops, |
1588 | .release = video_device_release, | 1571 | .release = video_device_release, |
1589 | .ioctl_ops = &video_ioctl_ops, | 1572 | .ioctl_ops = &video_ioctl_ops, |
1590 | .minor = -1, | ||
1591 | .tvnorms = V4L2_STD_NTSC_M, | 1573 | .tvnorms = V4L2_STD_NTSC_M, |
1592 | .current_norm = V4L2_STD_NTSC_M, | 1574 | .current_norm = V4L2_STD_NTSC_M, |
1593 | }; | 1575 | }; |
@@ -1676,25 +1658,23 @@ int au0828_analog_register(struct au0828_dev *dev, | |||
1676 | strcpy(dev->vbi_dev->name, "au0828a vbi"); | 1658 | strcpy(dev->vbi_dev->name, "au0828a vbi"); |
1677 | #endif | 1659 | #endif |
1678 | 1660 | ||
1679 | list_add_tail(&dev->au0828list, &au0828_devlist); | ||
1680 | |||
1681 | /* Register the v4l2 device */ | 1661 | /* Register the v4l2 device */ |
1662 | video_set_drvdata(dev->vdev, dev); | ||
1682 | retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1); | 1663 | retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1); |
1683 | if (retval != 0) { | 1664 | if (retval != 0) { |
1684 | dprintk(1, "unable to register video device (error = %d).\n", | 1665 | dprintk(1, "unable to register video device (error = %d).\n", |
1685 | retval); | 1666 | retval); |
1686 | list_del(&dev->au0828list); | ||
1687 | video_device_release(dev->vdev); | 1667 | video_device_release(dev->vdev); |
1688 | return -ENODEV; | 1668 | return -ENODEV; |
1689 | } | 1669 | } |
1690 | 1670 | ||
1691 | #ifdef VBI_IS_WORKING | 1671 | #ifdef VBI_IS_WORKING |
1692 | /* Register the vbi device */ | 1672 | /* Register the vbi device */ |
1673 | video_set_drvdata(dev->vbi_dev, dev); | ||
1693 | retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1); | 1674 | retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1); |
1694 | if (retval != 0) { | 1675 | if (retval != 0) { |
1695 | dprintk(1, "unable to register vbi device (error = %d).\n", | 1676 | dprintk(1, "unable to register vbi device (error = %d).\n", |
1696 | retval); | 1677 | retval); |
1697 | list_del(&dev->au0828list); | ||
1698 | video_device_release(dev->vbi_dev); | 1678 | video_device_release(dev->vbi_dev); |
1699 | video_device_release(dev->vdev); | 1679 | video_device_release(dev->vdev); |
1700 | return -ENODEV; | 1680 | return -ENODEV; |
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h index b977915efbd..207f32dec6a 100644 --- a/drivers/media/video/au0828/au0828.h +++ b/drivers/media/video/au0828/au0828.h | |||
@@ -192,7 +192,6 @@ struct au0828_dev { | |||
192 | struct au0828_dvb dvb; | 192 | struct au0828_dvb dvb; |
193 | 193 | ||
194 | /* Analog */ | 194 | /* Analog */ |
195 | struct list_head au0828list; | ||
196 | struct v4l2_device v4l2_dev; | 195 | struct v4l2_device v4l2_dev; |
197 | int users; | 196 | int users; |
198 | unsigned int stream_on:1; /* Locks streams */ | 197 | unsigned int stream_on:1; /* Locks streams */ |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a6724019c66..3182a406bdd 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -3206,24 +3206,24 @@ err: | |||
3206 | 3206 | ||
3207 | static int bttv_open(struct file *file) | 3207 | static int bttv_open(struct file *file) |
3208 | { | 3208 | { |
3209 | int minor = video_devdata(file)->minor; | 3209 | struct video_device *vdev = video_devdata(file); |
3210 | struct bttv *btv = video_drvdata(file); | 3210 | struct bttv *btv = video_drvdata(file); |
3211 | struct bttv_fh *fh; | 3211 | struct bttv_fh *fh; |
3212 | enum v4l2_buf_type type = 0; | 3212 | enum v4l2_buf_type type = 0; |
3213 | 3213 | ||
3214 | dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor); | 3214 | dprintk(KERN_DEBUG "bttv: open dev=%s\n", video_device_node_name(vdev)); |
3215 | 3215 | ||
3216 | lock_kernel(); | 3216 | if (vdev->vfl_type == VFL_TYPE_GRABBER) { |
3217 | if (btv->video_dev->minor == minor) { | ||
3218 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 3217 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
3219 | } else if (btv->vbi_dev->minor == minor) { | 3218 | } else if (vdev->vfl_type == VFL_TYPE_VBI) { |
3220 | type = V4L2_BUF_TYPE_VBI_CAPTURE; | 3219 | type = V4L2_BUF_TYPE_VBI_CAPTURE; |
3221 | } else { | 3220 | } else { |
3222 | WARN_ON(1); | 3221 | WARN_ON(1); |
3223 | unlock_kernel(); | ||
3224 | return -ENODEV; | 3222 | return -ENODEV; |
3225 | } | 3223 | } |
3226 | 3224 | ||
3225 | lock_kernel(); | ||
3226 | |||
3227 | dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", | 3227 | dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", |
3228 | btv->c.nr,v4l2_type_names[type]); | 3228 | btv->c.nr,v4l2_type_names[type]); |
3229 | 3229 | ||
@@ -3397,7 +3397,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { | |||
3397 | 3397 | ||
3398 | static struct video_device bttv_video_template = { | 3398 | static struct video_device bttv_video_template = { |
3399 | .fops = &bttv_fops, | 3399 | .fops = &bttv_fops, |
3400 | .minor = -1, | ||
3401 | .ioctl_ops = &bttv_ioctl_ops, | 3400 | .ioctl_ops = &bttv_ioctl_ops, |
3402 | .tvnorms = BTTV_NORMS, | 3401 | .tvnorms = BTTV_NORMS, |
3403 | .current_norm = V4L2_STD_PAL, | 3402 | .current_norm = V4L2_STD_PAL, |
@@ -3408,18 +3407,13 @@ static struct video_device bttv_video_template = { | |||
3408 | 3407 | ||
3409 | static int radio_open(struct file *file) | 3408 | static int radio_open(struct file *file) |
3410 | { | 3409 | { |
3411 | int minor = video_devdata(file)->minor; | 3410 | struct video_device *vdev = video_devdata(file); |
3412 | struct bttv *btv = video_drvdata(file); | 3411 | struct bttv *btv = video_drvdata(file); |
3413 | struct bttv_fh *fh; | 3412 | struct bttv_fh *fh; |
3414 | 3413 | ||
3415 | dprintk("bttv: open minor=%d\n",minor); | 3414 | dprintk("bttv: open dev=%s\n", video_device_node_name(vdev)); |
3416 | 3415 | ||
3417 | lock_kernel(); | 3416 | lock_kernel(); |
3418 | WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor); | ||
3419 | if (!btv->radio_dev || btv->radio_dev->minor != minor) { | ||
3420 | unlock_kernel(); | ||
3421 | return -ENODEV; | ||
3422 | } | ||
3423 | 3417 | ||
3424 | dprintk("bttv%d: open called (radio)\n",btv->c.nr); | 3418 | dprintk("bttv%d: open called (radio)\n",btv->c.nr); |
3425 | 3419 | ||
@@ -3640,7 +3634,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { | |||
3640 | 3634 | ||
3641 | static struct video_device radio_template = { | 3635 | static struct video_device radio_template = { |
3642 | .fops = &radio_fops, | 3636 | .fops = &radio_fops, |
3643 | .minor = -1, | ||
3644 | .ioctl_ops = &radio_ioctl_ops, | 3637 | .ioctl_ops = &radio_ioctl_ops, |
3645 | }; | 3638 | }; |
3646 | 3639 | ||
@@ -4208,21 +4201,21 @@ static struct video_device *vdev_init(struct bttv *btv, | |||
4208 | static void bttv_unregister_video(struct bttv *btv) | 4201 | static void bttv_unregister_video(struct bttv *btv) |
4209 | { | 4202 | { |
4210 | if (btv->video_dev) { | 4203 | if (btv->video_dev) { |
4211 | if (-1 != btv->video_dev->minor) | 4204 | if (video_is_registered(btv->video_dev)) |
4212 | video_unregister_device(btv->video_dev); | 4205 | video_unregister_device(btv->video_dev); |
4213 | else | 4206 | else |
4214 | video_device_release(btv->video_dev); | 4207 | video_device_release(btv->video_dev); |
4215 | btv->video_dev = NULL; | 4208 | btv->video_dev = NULL; |
4216 | } | 4209 | } |
4217 | if (btv->vbi_dev) { | 4210 | if (btv->vbi_dev) { |
4218 | if (-1 != btv->vbi_dev->minor) | 4211 | if (video_is_registered(btv->vbi_dev)) |
4219 | video_unregister_device(btv->vbi_dev); | 4212 | video_unregister_device(btv->vbi_dev); |
4220 | else | 4213 | else |
4221 | video_device_release(btv->vbi_dev); | 4214 | video_device_release(btv->vbi_dev); |
4222 | btv->vbi_dev = NULL; | 4215 | btv->vbi_dev = NULL; |
4223 | } | 4216 | } |
4224 | if (btv->radio_dev) { | 4217 | if (btv->radio_dev) { |
4225 | if (-1 != btv->radio_dev->minor) | 4218 | if (video_is_registered(btv->radio_dev)) |
4226 | video_unregister_device(btv->radio_dev); | 4219 | video_unregister_device(btv->radio_dev); |
4227 | else | 4220 | else |
4228 | video_device_release(btv->radio_dev); | 4221 | video_device_release(btv->radio_dev); |
@@ -4244,8 +4237,8 @@ static int __devinit bttv_register_video(struct bttv *btv) | |||
4244 | if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER, | 4237 | if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER, |
4245 | video_nr[btv->c.nr]) < 0) | 4238 | video_nr[btv->c.nr]) < 0) |
4246 | goto err; | 4239 | goto err; |
4247 | printk(KERN_INFO "bttv%d: registered device video%d\n", | 4240 | printk(KERN_INFO "bttv%d: registered device %s\n", |
4248 | btv->c.nr, btv->video_dev->num); | 4241 | btv->c.nr, video_device_node_name(btv->video_dev)); |
4249 | if (device_create_file(&btv->video_dev->dev, | 4242 | if (device_create_file(&btv->video_dev->dev, |
4250 | &dev_attr_card)<0) { | 4243 | &dev_attr_card)<0) { |
4251 | printk(KERN_ERR "bttv%d: device_create_file 'card' " | 4244 | printk(KERN_ERR "bttv%d: device_create_file 'card' " |
@@ -4261,8 +4254,8 @@ static int __devinit bttv_register_video(struct bttv *btv) | |||
4261 | if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI, | 4254 | if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI, |
4262 | vbi_nr[btv->c.nr]) < 0) | 4255 | vbi_nr[btv->c.nr]) < 0) |
4263 | goto err; | 4256 | goto err; |
4264 | printk(KERN_INFO "bttv%d: registered device vbi%d\n", | 4257 | printk(KERN_INFO "bttv%d: registered device %s\n", |
4265 | btv->c.nr, btv->vbi_dev->num); | 4258 | btv->c.nr, video_device_node_name(btv->vbi_dev)); |
4266 | 4259 | ||
4267 | if (!btv->has_radio) | 4260 | if (!btv->has_radio) |
4268 | return 0; | 4261 | return 0; |
@@ -4273,8 +4266,8 @@ static int __devinit bttv_register_video(struct bttv *btv) | |||
4273 | if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO, | 4266 | if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO, |
4274 | radio_nr[btv->c.nr]) < 0) | 4267 | radio_nr[btv->c.nr]) < 0) |
4275 | goto err; | 4268 | goto err; |
4276 | printk(KERN_INFO "bttv%d: registered device radio%d\n", | 4269 | printk(KERN_INFO "bttv%d: registered device %s\n", |
4277 | btv->c.nr, btv->radio_dev->num); | 4270 | btv->c.nr, video_device_node_name(btv->radio_dev)); |
4278 | 4271 | ||
4279 | /* all done */ | 4272 | /* all done */ |
4280 | return 0; | 4273 | return 0; |
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index beda363418b..63aa31a041e 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c | |||
@@ -40,7 +40,7 @@ static int i2c_debug; | |||
40 | static int i2c_hw; | 40 | static int i2c_hw; |
41 | static int i2c_scan; | 41 | static int i2c_scan; |
42 | module_param(i2c_debug, int, 0644); | 42 | module_param(i2c_debug, int, 0644); |
43 | MODULE_PARM_DESC(i2c_hw,"configure i2c debug level"); | 43 | MODULE_PARM_DESC(i2c_debug, "configure i2c debug level"); |
44 | module_param(i2c_hw, int, 0444); | 44 | module_param(i2c_hw, int, 0444); |
45 | MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, " | 45 | MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, " |
46 | "instead of software bitbang"); | 46 | "instead of software bitbang"); |
@@ -400,7 +400,7 @@ int __devinit init_bttv_i2c(struct bttv *btv) | |||
400 | That's why we probe 0x1a (~0x34) first. CB | 400 | That's why we probe 0x1a (~0x34) first. CB |
401 | */ | 401 | */ |
402 | const unsigned short addr_list[] = { | 402 | const unsigned short addr_list[] = { |
403 | 0x1a, 0x18, 0x4b, 0x64, 0x30, | 403 | 0x1a, 0x18, 0x4b, 0x64, 0x30, 0x71, |
404 | I2C_CLIENT_END | 404 | I2C_CLIENT_END |
405 | }; | 405 | }; |
406 | 406 | ||
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 84a957e52c4..277a092e121 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -368,7 +368,7 @@ int bttv_input_init(struct bttv *btv) | |||
368 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", | 368 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", |
369 | pci_name(btv->c.pci)); | 369 | pci_name(btv->c.pci)); |
370 | 370 | ||
371 | err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); | 371 | err = ir_input_init(input_dev, &ir->ir, ir_type); |
372 | if (err < 0) | 372 | if (err < 0) |
373 | goto err_out_free; | 373 | goto err_out_free; |
374 | 374 | ||
@@ -389,7 +389,7 @@ int bttv_input_init(struct bttv *btv) | |||
389 | bttv_ir_start(btv, ir); | 389 | bttv_ir_start(btv, ir); |
390 | 390 | ||
391 | /* all done */ | 391 | /* all done */ |
392 | err = input_register_device(btv->remote->dev); | 392 | err = ir_input_register(btv->remote->dev, ir_codes); |
393 | if (err) | 393 | if (err) |
394 | goto err_out_stop; | 394 | goto err_out_stop; |
395 | 395 | ||
@@ -403,8 +403,6 @@ int bttv_input_init(struct bttv *btv) | |||
403 | bttv_ir_stop(btv); | 403 | bttv_ir_stop(btv); |
404 | btv->remote = NULL; | 404 | btv->remote = NULL; |
405 | err_out_free: | 405 | err_out_free: |
406 | ir_input_free(input_dev); | ||
407 | input_free_device(input_dev); | ||
408 | kfree(ir); | 406 | kfree(ir); |
409 | return err; | 407 | return err; |
410 | } | 408 | } |
@@ -415,8 +413,7 @@ void bttv_input_fini(struct bttv *btv) | |||
415 | return; | 413 | return; |
416 | 414 | ||
417 | bttv_ir_stop(btv); | 415 | bttv_ir_stop(btv); |
418 | ir_input_free(btv->remote->dev); | 416 | ir_input_unregister(btv->remote->dev); |
419 | input_unregister_device(btv->remote->dev); | ||
420 | kfree(btv->remote); | 417 | kfree(btv->remote); |
421 | btv->remote = NULL; | 418 | btv->remote = NULL; |
422 | } | 419 | } |
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 85cf1778827..e2cbebab959 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
@@ -809,8 +809,8 @@ static int init_cqcam(struct parport *port) | |||
809 | return -ENODEV; | 809 | return -ENODEV; |
810 | } | 810 | } |
811 | 811 | ||
812 | printk(KERN_INFO "video%d: Colour QuickCam found on %s\n", | 812 | printk(KERN_INFO "%s: Colour QuickCam found on %s\n", |
813 | qcam->vdev.num, qcam->pport->name); | 813 | video_device_node_name(&qcam->vdev), qcam->pport->name); |
814 | 814 | ||
815 | qcams[num_cams++] = qcam; | 815 | qcams[num_cams++] = qcam; |
816 | 816 | ||
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 10230cb3d21..7bb9c1ec781 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
@@ -1723,7 +1723,6 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { | |||
1723 | 1723 | ||
1724 | static struct video_device cafe_v4l_template = { | 1724 | static struct video_device cafe_v4l_template = { |
1725 | .name = "cafe", | 1725 | .name = "cafe", |
1726 | .minor = -1, /* Get one dynamically */ | ||
1727 | .tvnorms = V4L2_STD_NTSC_M, | 1726 | .tvnorms = V4L2_STD_NTSC_M, |
1728 | .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ | 1727 | .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ |
1729 | 1728 | ||
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 2377313c041..551ddf216a4 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/fs.h> | 32 | #include <linux/fs.h> |
33 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/seq_file.h> | ||
35 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
36 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
37 | #include <linux/ctype.h> | 38 | #include <linux/ctype.h> |
@@ -244,72 +245,67 @@ static void rvfree(void *mem, unsigned long size) | |||
244 | #ifdef CONFIG_PROC_FS | 245 | #ifdef CONFIG_PROC_FS |
245 | static struct proc_dir_entry *cpia_proc_root=NULL; | 246 | static struct proc_dir_entry *cpia_proc_root=NULL; |
246 | 247 | ||
247 | static int cpia_read_proc(char *page, char **start, off_t off, | 248 | static int cpia_proc_show(struct seq_file *m, void *v) |
248 | int count, int *eof, void *data) | ||
249 | { | 249 | { |
250 | char *out = page; | 250 | struct cam_data *cam = m->private; |
251 | int len, tmp; | 251 | int tmp; |
252 | struct cam_data *cam = data; | ||
253 | char tmpstr[29]; | 252 | char tmpstr[29]; |
254 | 253 | ||
255 | /* IMPORTANT: This output MUST be kept under PAGE_SIZE | 254 | seq_printf(m, "read-only\n-----------------------\n"); |
256 | * or we need to get more sophisticated. */ | 255 | seq_printf(m, "V4L Driver version: %d.%d.%d\n", |
257 | |||
258 | out += sprintf(out, "read-only\n-----------------------\n"); | ||
259 | out += sprintf(out, "V4L Driver version: %d.%d.%d\n", | ||
260 | CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER); | 256 | CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER); |
261 | out += sprintf(out, "CPIA Version: %d.%02d (%d.%d)\n", | 257 | seq_printf(m, "CPIA Version: %d.%02d (%d.%d)\n", |
262 | cam->params.version.firmwareVersion, | 258 | cam->params.version.firmwareVersion, |
263 | cam->params.version.firmwareRevision, | 259 | cam->params.version.firmwareRevision, |
264 | cam->params.version.vcVersion, | 260 | cam->params.version.vcVersion, |
265 | cam->params.version.vcRevision); | 261 | cam->params.version.vcRevision); |
266 | out += sprintf(out, "CPIA PnP-ID: %04x:%04x:%04x\n", | 262 | seq_printf(m, "CPIA PnP-ID: %04x:%04x:%04x\n", |
267 | cam->params.pnpID.vendor, cam->params.pnpID.product, | 263 | cam->params.pnpID.vendor, cam->params.pnpID.product, |
268 | cam->params.pnpID.deviceRevision); | 264 | cam->params.pnpID.deviceRevision); |
269 | out += sprintf(out, "VP-Version: %d.%d %04x\n", | 265 | seq_printf(m, "VP-Version: %d.%d %04x\n", |
270 | cam->params.vpVersion.vpVersion, | 266 | cam->params.vpVersion.vpVersion, |
271 | cam->params.vpVersion.vpRevision, | 267 | cam->params.vpVersion.vpRevision, |
272 | cam->params.vpVersion.cameraHeadID); | 268 | cam->params.vpVersion.cameraHeadID); |
273 | 269 | ||
274 | out += sprintf(out, "system_state: %#04x\n", | 270 | seq_printf(m, "system_state: %#04x\n", |
275 | cam->params.status.systemState); | 271 | cam->params.status.systemState); |
276 | out += sprintf(out, "grab_state: %#04x\n", | 272 | seq_printf(m, "grab_state: %#04x\n", |
277 | cam->params.status.grabState); | 273 | cam->params.status.grabState); |
278 | out += sprintf(out, "stream_state: %#04x\n", | 274 | seq_printf(m, "stream_state: %#04x\n", |
279 | cam->params.status.streamState); | 275 | cam->params.status.streamState); |
280 | out += sprintf(out, "fatal_error: %#04x\n", | 276 | seq_printf(m, "fatal_error: %#04x\n", |
281 | cam->params.status.fatalError); | 277 | cam->params.status.fatalError); |
282 | out += sprintf(out, "cmd_error: %#04x\n", | 278 | seq_printf(m, "cmd_error: %#04x\n", |
283 | cam->params.status.cmdError); | 279 | cam->params.status.cmdError); |
284 | out += sprintf(out, "debug_flags: %#04x\n", | 280 | seq_printf(m, "debug_flags: %#04x\n", |
285 | cam->params.status.debugFlags); | 281 | cam->params.status.debugFlags); |
286 | out += sprintf(out, "vp_status: %#04x\n", | 282 | seq_printf(m, "vp_status: %#04x\n", |
287 | cam->params.status.vpStatus); | 283 | cam->params.status.vpStatus); |
288 | out += sprintf(out, "error_code: %#04x\n", | 284 | seq_printf(m, "error_code: %#04x\n", |
289 | cam->params.status.errorCode); | 285 | cam->params.status.errorCode); |
290 | /* QX3 specific entries */ | 286 | /* QX3 specific entries */ |
291 | if (cam->params.qx3.qx3_detected) { | 287 | if (cam->params.qx3.qx3_detected) { |
292 | out += sprintf(out, "button: %4d\n", | 288 | seq_printf(m, "button: %4d\n", |
293 | cam->params.qx3.button); | 289 | cam->params.qx3.button); |
294 | out += sprintf(out, "cradled: %4d\n", | 290 | seq_printf(m, "cradled: %4d\n", |
295 | cam->params.qx3.cradled); | 291 | cam->params.qx3.cradled); |
296 | } | 292 | } |
297 | out += sprintf(out, "video_size: %s\n", | 293 | seq_printf(m, "video_size: %s\n", |
298 | cam->params.format.videoSize == VIDEOSIZE_CIF ? | 294 | cam->params.format.videoSize == VIDEOSIZE_CIF ? |
299 | "CIF " : "QCIF"); | 295 | "CIF " : "QCIF"); |
300 | out += sprintf(out, "roi: (%3d, %3d) to (%3d, %3d)\n", | 296 | seq_printf(m, "roi: (%3d, %3d) to (%3d, %3d)\n", |
301 | cam->params.roi.colStart*8, | 297 | cam->params.roi.colStart*8, |
302 | cam->params.roi.rowStart*4, | 298 | cam->params.roi.rowStart*4, |
303 | cam->params.roi.colEnd*8, | 299 | cam->params.roi.colEnd*8, |
304 | cam->params.roi.rowEnd*4); | 300 | cam->params.roi.rowEnd*4); |
305 | out += sprintf(out, "actual_fps: %3d\n", cam->fps); | 301 | seq_printf(m, "actual_fps: %3d\n", cam->fps); |
306 | out += sprintf(out, "transfer_rate: %4dkB/s\n", | 302 | seq_printf(m, "transfer_rate: %4dkB/s\n", |
307 | cam->transfer_rate); | 303 | cam->transfer_rate); |
308 | 304 | ||
309 | out += sprintf(out, "\nread-write\n"); | 305 | seq_printf(m, "\nread-write\n"); |
310 | out += sprintf(out, "----------------------- current min" | 306 | seq_printf(m, "----------------------- current min" |
311 | " max default comment\n"); | 307 | " max default comment\n"); |
312 | out += sprintf(out, "brightness: %8d %8d %8d %8d\n", | 308 | seq_printf(m, "brightness: %8d %8d %8d %8d\n", |
313 | cam->params.colourParams.brightness, 0, 100, 50); | 309 | cam->params.colourParams.brightness, 0, 100, 50); |
314 | if (cam->params.version.firmwareVersion == 1 && | 310 | if (cam->params.version.firmwareVersion == 1 && |
315 | cam->params.version.firmwareRevision == 2) | 311 | cam->params.version.firmwareRevision == 2) |
@@ -318,26 +314,26 @@ static int cpia_read_proc(char *page, char **start, off_t off, | |||
318 | else | 314 | else |
319 | tmp = 96; | 315 | tmp = 96; |
320 | 316 | ||
321 | out += sprintf(out, "contrast: %8d %8d %8d %8d" | 317 | seq_printf(m, "contrast: %8d %8d %8d %8d" |
322 | " steps of 8\n", | 318 | " steps of 8\n", |
323 | cam->params.colourParams.contrast, 0, tmp, 48); | 319 | cam->params.colourParams.contrast, 0, tmp, 48); |
324 | out += sprintf(out, "saturation: %8d %8d %8d %8d\n", | 320 | seq_printf(m, "saturation: %8d %8d %8d %8d\n", |
325 | cam->params.colourParams.saturation, 0, 100, 50); | 321 | cam->params.colourParams.saturation, 0, 100, 50); |
326 | tmp = (25000+5000*cam->params.sensorFps.baserate)/ | 322 | tmp = (25000+5000*cam->params.sensorFps.baserate)/ |
327 | (1<<cam->params.sensorFps.divisor); | 323 | (1<<cam->params.sensorFps.divisor); |
328 | out += sprintf(out, "sensor_fps: %4d.%03d %8d %8d %8d\n", | 324 | seq_printf(m, "sensor_fps: %4d.%03d %8d %8d %8d\n", |
329 | tmp/1000, tmp%1000, 3, 30, 15); | 325 | tmp/1000, tmp%1000, 3, 30, 15); |
330 | out += sprintf(out, "stream_start_line: %8d %8d %8d %8d\n", | 326 | seq_printf(m, "stream_start_line: %8d %8d %8d %8d\n", |
331 | 2*cam->params.streamStartLine, 0, | 327 | 2*cam->params.streamStartLine, 0, |
332 | cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144, | 328 | cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144, |
333 | cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120); | 329 | cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120); |
334 | out += sprintf(out, "sub_sample: %8s %8s %8s %8s\n", | 330 | seq_printf(m, "sub_sample: %8s %8s %8s %8s\n", |
335 | cam->params.format.subSample == SUBSAMPLE_420 ? | 331 | cam->params.format.subSample == SUBSAMPLE_420 ? |
336 | "420" : "422", "420", "422", "422"); | 332 | "420" : "422", "420", "422", "422"); |
337 | out += sprintf(out, "yuv_order: %8s %8s %8s %8s\n", | 333 | seq_printf(m, "yuv_order: %8s %8s %8s %8s\n", |
338 | cam->params.format.yuvOrder == YUVORDER_YUYV ? | 334 | cam->params.format.yuvOrder == YUVORDER_YUYV ? |
339 | "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV"); | 335 | "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV"); |
340 | out += sprintf(out, "ecp_timing: %8s %8s %8s %8s\n", | 336 | seq_printf(m, "ecp_timing: %8s %8s %8s %8s\n", |
341 | cam->params.ecpTiming ? "slow" : "normal", "slow", | 337 | cam->params.ecpTiming ? "slow" : "normal", "slow", |
342 | "normal", "normal"); | 338 | "normal", "normal"); |
343 | 339 | ||
@@ -346,13 +342,13 @@ static int cpia_read_proc(char *page, char **start, off_t off, | |||
346 | } else { | 342 | } else { |
347 | sprintf(tmpstr, "manual"); | 343 | sprintf(tmpstr, "manual"); |
348 | } | 344 | } |
349 | out += sprintf(out, "color_balance_mode: %8s %8s %8s" | 345 | seq_printf(m, "color_balance_mode: %8s %8s %8s" |
350 | " %8s\n", tmpstr, "manual", "auto", "auto"); | 346 | " %8s\n", tmpstr, "manual", "auto", "auto"); |
351 | out += sprintf(out, "red_gain: %8d %8d %8d %8d\n", | 347 | seq_printf(m, "red_gain: %8d %8d %8d %8d\n", |
352 | cam->params.colourBalance.redGain, 0, 212, 32); | 348 | cam->params.colourBalance.redGain, 0, 212, 32); |
353 | out += sprintf(out, "green_gain: %8d %8d %8d %8d\n", | 349 | seq_printf(m, "green_gain: %8d %8d %8d %8d\n", |
354 | cam->params.colourBalance.greenGain, 0, 212, 6); | 350 | cam->params.colourBalance.greenGain, 0, 212, 6); |
355 | out += sprintf(out, "blue_gain: %8d %8d %8d %8d\n", | 351 | seq_printf(m, "blue_gain: %8d %8d %8d %8d\n", |
356 | cam->params.colourBalance.blueGain, 0, 212, 92); | 352 | cam->params.colourBalance.blueGain, 0, 212, 92); |
357 | 353 | ||
358 | if (cam->params.version.firmwareVersion == 1 && | 354 | if (cam->params.version.firmwareVersion == 1 && |
@@ -363,10 +359,10 @@ static int cpia_read_proc(char *page, char **start, off_t off, | |||
363 | sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2); | 359 | sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2); |
364 | 360 | ||
365 | if (cam->params.exposure.gainMode == 0) | 361 | if (cam->params.exposure.gainMode == 0) |
366 | out += sprintf(out, "max_gain: unknown %28s" | 362 | seq_printf(m, "max_gain: unknown %28s" |
367 | " powers of 2\n", tmpstr); | 363 | " powers of 2\n", tmpstr); |
368 | else | 364 | else |
369 | out += sprintf(out, "max_gain: %8d %28s" | 365 | seq_printf(m, "max_gain: %8d %28s" |
370 | " 1,2,4 or 8 \n", | 366 | " 1,2,4 or 8 \n", |
371 | 1<<(cam->params.exposure.gainMode-1), tmpstr); | 367 | 1<<(cam->params.exposure.gainMode-1), tmpstr); |
372 | 368 | ||
@@ -382,12 +378,12 @@ static int cpia_read_proc(char *page, char **start, off_t off, | |||
382 | sprintf(tmpstr, "unknown"); | 378 | sprintf(tmpstr, "unknown"); |
383 | break; | 379 | break; |
384 | } | 380 | } |
385 | out += sprintf(out, "exposure_mode: %8s %8s %8s" | 381 | seq_printf(m, "exposure_mode: %8s %8s %8s" |
386 | " %8s\n", tmpstr, "manual", "auto", "auto"); | 382 | " %8s\n", tmpstr, "manual", "auto", "auto"); |
387 | out += sprintf(out, "centre_weight: %8s %8s %8s %8s\n", | 383 | seq_printf(m, "centre_weight: %8s %8s %8s %8s\n", |
388 | (2-cam->params.exposure.centreWeight) ? "on" : "off", | 384 | (2-cam->params.exposure.centreWeight) ? "on" : "off", |
389 | "off", "on", "on"); | 385 | "off", "on", "on"); |
390 | out += sprintf(out, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n", | 386 | seq_printf(m, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n", |
391 | 1<<cam->params.exposure.gain, 1, 1); | 387 | 1<<cam->params.exposure.gain, 1, 1); |
392 | if (cam->params.version.firmwareVersion == 1 && | 388 | if (cam->params.version.firmwareVersion == 1 && |
393 | cam->params.version.firmwareRevision == 2) | 389 | cam->params.version.firmwareRevision == 2) |
@@ -396,7 +392,7 @@ static int cpia_read_proc(char *page, char **start, off_t off, | |||
396 | else | 392 | else |
397 | tmp = 510; | 393 | tmp = 510; |
398 | 394 | ||
399 | out += sprintf(out, "fine_exp: %8d %8d %8d %8d\n", | 395 | seq_printf(m, "fine_exp: %8d %8d %8d %8d\n", |
400 | cam->params.exposure.fineExp*2, 0, tmp, 0); | 396 | cam->params.exposure.fineExp*2, 0, tmp, 0); |
401 | if (cam->params.version.firmwareVersion == 1 && | 397 | if (cam->params.version.firmwareVersion == 1 && |
402 | cam->params.version.firmwareRevision == 2) | 398 | cam->params.version.firmwareRevision == 2) |
@@ -405,127 +401,122 @@ static int cpia_read_proc(char *page, char **start, off_t off, | |||
405 | else | 401 | else |
406 | tmp = MAX_EXP; | 402 | tmp = MAX_EXP; |
407 | 403 | ||
408 | out += sprintf(out, "coarse_exp: %8d %8d %8d" | 404 | seq_printf(m, "coarse_exp: %8d %8d %8d" |
409 | " %8d\n", cam->params.exposure.coarseExpLo+ | 405 | " %8d\n", cam->params.exposure.coarseExpLo+ |
410 | 256*cam->params.exposure.coarseExpHi, 0, tmp, 185); | 406 | 256*cam->params.exposure.coarseExpHi, 0, tmp, 185); |
411 | out += sprintf(out, "red_comp: %8d %8d %8d %8d\n", | 407 | seq_printf(m, "red_comp: %8d %8d %8d %8d\n", |
412 | cam->params.exposure.redComp, COMP_RED, 255, COMP_RED); | 408 | cam->params.exposure.redComp, COMP_RED, 255, COMP_RED); |
413 | out += sprintf(out, "green1_comp: %8d %8d %8d %8d\n", | 409 | seq_printf(m, "green1_comp: %8d %8d %8d %8d\n", |
414 | cam->params.exposure.green1Comp, COMP_GREEN1, 255, | 410 | cam->params.exposure.green1Comp, COMP_GREEN1, 255, |
415 | COMP_GREEN1); | 411 | COMP_GREEN1); |
416 | out += sprintf(out, "green2_comp: %8d %8d %8d %8d\n", | 412 | seq_printf(m, "green2_comp: %8d %8d %8d %8d\n", |
417 | cam->params.exposure.green2Comp, COMP_GREEN2, 255, | 413 | cam->params.exposure.green2Comp, COMP_GREEN2, 255, |
418 | COMP_GREEN2); | 414 | COMP_GREEN2); |
419 | out += sprintf(out, "blue_comp: %8d %8d %8d %8d\n", | 415 | seq_printf(m, "blue_comp: %8d %8d %8d %8d\n", |
420 | cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE); | 416 | cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE); |
421 | 417 | ||
422 | out += sprintf(out, "apcor_gain1: %#8x %#8x %#8x %#8x\n", | 418 | seq_printf(m, "apcor_gain1: %#8x %#8x %#8x %#8x\n", |
423 | cam->params.apcor.gain1, 0, 0xff, 0x1c); | 419 | cam->params.apcor.gain1, 0, 0xff, 0x1c); |
424 | out += sprintf(out, "apcor_gain2: %#8x %#8x %#8x %#8x\n", | 420 | seq_printf(m, "apcor_gain2: %#8x %#8x %#8x %#8x\n", |
425 | cam->params.apcor.gain2, 0, 0xff, 0x1a); | 421 | cam->params.apcor.gain2, 0, 0xff, 0x1a); |
426 | out += sprintf(out, "apcor_gain4: %#8x %#8x %#8x %#8x\n", | 422 | seq_printf(m, "apcor_gain4: %#8x %#8x %#8x %#8x\n", |
427 | cam->params.apcor.gain4, 0, 0xff, 0x2d); | 423 | cam->params.apcor.gain4, 0, 0xff, 0x2d); |
428 | out += sprintf(out, "apcor_gain8: %#8x %#8x %#8x %#8x\n", | 424 | seq_printf(m, "apcor_gain8: %#8x %#8x %#8x %#8x\n", |
429 | cam->params.apcor.gain8, 0, 0xff, 0x2a); | 425 | cam->params.apcor.gain8, 0, 0xff, 0x2a); |
430 | out += sprintf(out, "vl_offset_gain1: %8d %8d %8d %8d\n", | 426 | seq_printf(m, "vl_offset_gain1: %8d %8d %8d %8d\n", |
431 | cam->params.vlOffset.gain1, 0, 255, 24); | 427 | cam->params.vlOffset.gain1, 0, 255, 24); |
432 | out += sprintf(out, "vl_offset_gain2: %8d %8d %8d %8d\n", | 428 | seq_printf(m, "vl_offset_gain2: %8d %8d %8d %8d\n", |
433 | cam->params.vlOffset.gain2, 0, 255, 28); | 429 | cam->params.vlOffset.gain2, 0, 255, 28); |
434 | out += sprintf(out, "vl_offset_gain4: %8d %8d %8d %8d\n", | 430 | seq_printf(m, "vl_offset_gain4: %8d %8d %8d %8d\n", |
435 | cam->params.vlOffset.gain4, 0, 255, 30); | 431 | cam->params.vlOffset.gain4, 0, 255, 30); |
436 | out += sprintf(out, "vl_offset_gain8: %8d %8d %8d %8d\n", | 432 | seq_printf(m, "vl_offset_gain8: %8d %8d %8d %8d\n", |
437 | cam->params.vlOffset.gain8, 0, 255, 30); | 433 | cam->params.vlOffset.gain8, 0, 255, 30); |
438 | out += sprintf(out, "flicker_control: %8s %8s %8s %8s\n", | 434 | seq_printf(m, "flicker_control: %8s %8s %8s %8s\n", |
439 | cam->params.flickerControl.flickerMode ? "on" : "off", | 435 | cam->params.flickerControl.flickerMode ? "on" : "off", |
440 | "off", "on", "off"); | 436 | "off", "on", "off"); |
441 | out += sprintf(out, "mains_frequency: %8d %8d %8d %8d" | 437 | seq_printf(m, "mains_frequency: %8d %8d %8d %8d" |
442 | " only 50/60\n", | 438 | " only 50/60\n", |
443 | cam->mainsFreq ? 60 : 50, 50, 60, 50); | 439 | cam->mainsFreq ? 60 : 50, 50, 60, 50); |
444 | if(cam->params.flickerControl.allowableOverExposure < 0) | 440 | if(cam->params.flickerControl.allowableOverExposure < 0) |
445 | out += sprintf(out, "allowable_overexposure: %4dauto auto %8d auto\n", | 441 | seq_printf(m, "allowable_overexposure: %4dauto auto %8d auto\n", |
446 | -cam->params.flickerControl.allowableOverExposure, | 442 | -cam->params.flickerControl.allowableOverExposure, |
447 | 255); | 443 | 255); |
448 | else | 444 | else |
449 | out += sprintf(out, "allowable_overexposure: %8d auto %8d auto\n", | 445 | seq_printf(m, "allowable_overexposure: %8d auto %8d auto\n", |
450 | cam->params.flickerControl.allowableOverExposure, | 446 | cam->params.flickerControl.allowableOverExposure, |
451 | 255); | 447 | 255); |
452 | out += sprintf(out, "compression_mode: "); | 448 | seq_printf(m, "compression_mode: "); |
453 | switch(cam->params.compression.mode) { | 449 | switch(cam->params.compression.mode) { |
454 | case CPIA_COMPRESSION_NONE: | 450 | case CPIA_COMPRESSION_NONE: |
455 | out += sprintf(out, "%8s", "none"); | 451 | seq_printf(m, "%8s", "none"); |
456 | break; | 452 | break; |
457 | case CPIA_COMPRESSION_AUTO: | 453 | case CPIA_COMPRESSION_AUTO: |
458 | out += sprintf(out, "%8s", "auto"); | 454 | seq_printf(m, "%8s", "auto"); |
459 | break; | 455 | break; |
460 | case CPIA_COMPRESSION_MANUAL: | 456 | case CPIA_COMPRESSION_MANUAL: |
461 | out += sprintf(out, "%8s", "manual"); | 457 | seq_printf(m, "%8s", "manual"); |
462 | break; | 458 | break; |
463 | default: | 459 | default: |
464 | out += sprintf(out, "%8s", "unknown"); | 460 | seq_printf(m, "%8s", "unknown"); |
465 | break; | 461 | break; |
466 | } | 462 | } |
467 | out += sprintf(out, " none,auto,manual auto\n"); | 463 | seq_printf(m, " none,auto,manual auto\n"); |
468 | out += sprintf(out, "decimation_enable: %8s %8s %8s %8s\n", | 464 | seq_printf(m, "decimation_enable: %8s %8s %8s %8s\n", |
469 | cam->params.compression.decimation == | 465 | cam->params.compression.decimation == |
470 | DECIMATION_ENAB ? "on":"off", "off", "on", | 466 | DECIMATION_ENAB ? "on":"off", "off", "on", |
471 | "off"); | 467 | "off"); |
472 | out += sprintf(out, "compression_target: %9s %9s %9s %9s\n", | 468 | seq_printf(m, "compression_target: %9s %9s %9s %9s\n", |
473 | cam->params.compressionTarget.frTargeting == | 469 | cam->params.compressionTarget.frTargeting == |
474 | CPIA_COMPRESSION_TARGET_FRAMERATE ? | 470 | CPIA_COMPRESSION_TARGET_FRAMERATE ? |
475 | "framerate":"quality", | 471 | "framerate":"quality", |
476 | "framerate", "quality", "quality"); | 472 | "framerate", "quality", "quality"); |
477 | out += sprintf(out, "target_framerate: %8d %8d %8d %8d\n", | 473 | seq_printf(m, "target_framerate: %8d %8d %8d %8d\n", |
478 | cam->params.compressionTarget.targetFR, 1, 30, 15); | 474 | cam->params.compressionTarget.targetFR, 1, 30, 15); |
479 | out += sprintf(out, "target_quality: %8d %8d %8d %8d\n", | 475 | seq_printf(m, "target_quality: %8d %8d %8d %8d\n", |
480 | cam->params.compressionTarget.targetQ, 1, 64, 5); | 476 | cam->params.compressionTarget.targetQ, 1, 64, 5); |
481 | out += sprintf(out, "y_threshold: %8d %8d %8d %8d\n", | 477 | seq_printf(m, "y_threshold: %8d %8d %8d %8d\n", |
482 | cam->params.yuvThreshold.yThreshold, 0, 31, 6); | 478 | cam->params.yuvThreshold.yThreshold, 0, 31, 6); |
483 | out += sprintf(out, "uv_threshold: %8d %8d %8d %8d\n", | 479 | seq_printf(m, "uv_threshold: %8d %8d %8d %8d\n", |
484 | cam->params.yuvThreshold.uvThreshold, 0, 31, 6); | 480 | cam->params.yuvThreshold.uvThreshold, 0, 31, 6); |
485 | out += sprintf(out, "hysteresis: %8d %8d %8d %8d\n", | 481 | seq_printf(m, "hysteresis: %8d %8d %8d %8d\n", |
486 | cam->params.compressionParams.hysteresis, 0, 255, 3); | 482 | cam->params.compressionParams.hysteresis, 0, 255, 3); |
487 | out += sprintf(out, "threshold_max: %8d %8d %8d %8d\n", | 483 | seq_printf(m, "threshold_max: %8d %8d %8d %8d\n", |
488 | cam->params.compressionParams.threshMax, 0, 255, 11); | 484 | cam->params.compressionParams.threshMax, 0, 255, 11); |
489 | out += sprintf(out, "small_step: %8d %8d %8d %8d\n", | 485 | seq_printf(m, "small_step: %8d %8d %8d %8d\n", |
490 | cam->params.compressionParams.smallStep, 0, 255, 1); | 486 | cam->params.compressionParams.smallStep, 0, 255, 1); |
491 | out += sprintf(out, "large_step: %8d %8d %8d %8d\n", | 487 | seq_printf(m, "large_step: %8d %8d %8d %8d\n", |
492 | cam->params.compressionParams.largeStep, 0, 255, 3); | 488 | cam->params.compressionParams.largeStep, 0, 255, 3); |
493 | out += sprintf(out, "decimation_hysteresis: %8d %8d %8d %8d\n", | 489 | seq_printf(m, "decimation_hysteresis: %8d %8d %8d %8d\n", |
494 | cam->params.compressionParams.decimationHysteresis, | 490 | cam->params.compressionParams.decimationHysteresis, |
495 | 0, 255, 2); | 491 | 0, 255, 2); |
496 | out += sprintf(out, "fr_diff_step_thresh: %8d %8d %8d %8d\n", | 492 | seq_printf(m, "fr_diff_step_thresh: %8d %8d %8d %8d\n", |
497 | cam->params.compressionParams.frDiffStepThresh, | 493 | cam->params.compressionParams.frDiffStepThresh, |
498 | 0, 255, 5); | 494 | 0, 255, 5); |
499 | out += sprintf(out, "q_diff_step_thresh: %8d %8d %8d %8d\n", | 495 | seq_printf(m, "q_diff_step_thresh: %8d %8d %8d %8d\n", |
500 | cam->params.compressionParams.qDiffStepThresh, | 496 | cam->params.compressionParams.qDiffStepThresh, |
501 | 0, 255, 3); | 497 | 0, 255, 3); |
502 | out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n", | 498 | seq_printf(m, "decimation_thresh_mod: %8d %8d %8d %8d\n", |
503 | cam->params.compressionParams.decimationThreshMod, | 499 | cam->params.compressionParams.decimationThreshMod, |
504 | 0, 255, 2); | 500 | 0, 255, 2); |
505 | /* QX3 specific entries */ | 501 | /* QX3 specific entries */ |
506 | if (cam->params.qx3.qx3_detected) { | 502 | if (cam->params.qx3.qx3_detected) { |
507 | out += sprintf(out, "toplight: %8s %8s %8s %8s\n", | 503 | seq_printf(m, "toplight: %8s %8s %8s %8s\n", |
508 | cam->params.qx3.toplight ? "on" : "off", | 504 | cam->params.qx3.toplight ? "on" : "off", |
509 | "off", "on", "off"); | 505 | "off", "on", "off"); |
510 | out += sprintf(out, "bottomlight: %8s %8s %8s %8s\n", | 506 | seq_printf(m, "bottomlight: %8s %8s %8s %8s\n", |
511 | cam->params.qx3.bottomlight ? "on" : "off", | 507 | cam->params.qx3.bottomlight ? "on" : "off", |
512 | "off", "on", "off"); | 508 | "off", "on", "off"); |
513 | } | 509 | } |
514 | 510 | ||
515 | len = out - page; | 511 | return 0; |
516 | len -= off; | ||
517 | if (len < count) { | ||
518 | *eof = 1; | ||
519 | if (len <= 0) return 0; | ||
520 | } else | ||
521 | len = count; | ||
522 | |||
523 | *start = page + off; | ||
524 | return len; | ||
525 | } | 512 | } |
526 | 513 | ||
514 | static int cpia_proc_open(struct inode *inode, struct file *file) | ||
515 | { | ||
516 | return single_open(file, cpia_proc_show, PDE(inode)->data); | ||
517 | } | ||
527 | 518 | ||
528 | static int match(char *checkstr, char **buffer, unsigned long *count, | 519 | static int match(char *checkstr, char **buffer, size_t *count, |
529 | int *find_colon, int *err) | 520 | int *find_colon, int *err) |
530 | { | 521 | { |
531 | int ret, colon_found = 1; | 522 | int ret, colon_found = 1; |
@@ -551,7 +542,7 @@ static int match(char *checkstr, char **buffer, unsigned long *count, | |||
551 | return ret; | 542 | return ret; |
552 | } | 543 | } |
553 | 544 | ||
554 | static unsigned long int value(char **buffer, unsigned long *count, int *err) | 545 | static unsigned long int value(char **buffer, size_t *count, int *err) |
555 | { | 546 | { |
556 | char *p; | 547 | char *p; |
557 | unsigned long int ret; | 548 | unsigned long int ret; |
@@ -565,10 +556,10 @@ static unsigned long int value(char **buffer, unsigned long *count, int *err) | |||
565 | return ret; | 556 | return ret; |
566 | } | 557 | } |
567 | 558 | ||
568 | static int cpia_write_proc(struct file *file, const char __user *buf, | 559 | static ssize_t cpia_proc_write(struct file *file, const char __user *buf, |
569 | unsigned long count, void *data) | 560 | size_t count, loff_t *pos) |
570 | { | 561 | { |
571 | struct cam_data *cam = data; | 562 | struct cam_data *cam = PDE(file->f_path.dentry->d_inode)->data; |
572 | struct cam_params new_params; | 563 | struct cam_params new_params; |
573 | char *page, *buffer; | 564 | char *page, *buffer; |
574 | int retval, find_colon; | 565 | int retval, find_colon; |
@@ -582,7 +573,7 @@ static int cpia_write_proc(struct file *file, const char __user *buf, | |||
582 | * from the comx driver | 573 | * from the comx driver |
583 | */ | 574 | */ |
584 | if (count > PAGE_SIZE) { | 575 | if (count > PAGE_SIZE) { |
585 | printk(KERN_ERR "count is %lu > %d!!!\n", count, (int)PAGE_SIZE); | 576 | printk(KERN_ERR "count is %zu > %d!!!\n", count, (int)PAGE_SIZE); |
586 | return -ENOSPC; | 577 | return -ENOSPC; |
587 | } | 578 | } |
588 | 579 | ||
@@ -1340,23 +1331,28 @@ out: | |||
1340 | return retval; | 1331 | return retval; |
1341 | } | 1332 | } |
1342 | 1333 | ||
1334 | static const struct file_operations cpia_proc_fops = { | ||
1335 | .owner = THIS_MODULE, | ||
1336 | .open = cpia_proc_open, | ||
1337 | .read = seq_read, | ||
1338 | .llseek = seq_lseek, | ||
1339 | .release = single_release, | ||
1340 | .write = cpia_proc_write, | ||
1341 | }; | ||
1342 | |||
1343 | static void create_proc_cpia_cam(struct cam_data *cam) | 1343 | static void create_proc_cpia_cam(struct cam_data *cam) |
1344 | { | 1344 | { |
1345 | char name[5 + 1 + 10 + 1]; | ||
1346 | struct proc_dir_entry *ent; | 1345 | struct proc_dir_entry *ent; |
1347 | 1346 | ||
1348 | if (!cpia_proc_root || !cam) | 1347 | if (!cpia_proc_root || !cam) |
1349 | return; | 1348 | return; |
1350 | 1349 | ||
1351 | snprintf(name, sizeof(name), "video%d", cam->vdev.num); | 1350 | ent = proc_create_data(video_device_node_name(&cam->vdev), |
1352 | 1351 | S_IRUGO|S_IWUSR, cpia_proc_root, | |
1353 | ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root); | 1352 | &cpia_proc_fops, cam); |
1354 | if (!ent) | 1353 | if (!ent) |
1355 | return; | 1354 | return; |
1356 | 1355 | ||
1357 | ent->data = cam; | ||
1358 | ent->read_proc = cpia_read_proc; | ||
1359 | ent->write_proc = cpia_write_proc; | ||
1360 | /* | 1356 | /* |
1361 | size of the proc entry is 3736 bytes for the standard webcam; | 1357 | size of the proc entry is 3736 bytes for the standard webcam; |
1362 | the extra features of the QX3 microscope add 189 bytes. | 1358 | the extra features of the QX3 microscope add 189 bytes. |
@@ -1368,13 +1364,10 @@ static void create_proc_cpia_cam(struct cam_data *cam) | |||
1368 | 1364 | ||
1369 | static void destroy_proc_cpia_cam(struct cam_data *cam) | 1365 | static void destroy_proc_cpia_cam(struct cam_data *cam) |
1370 | { | 1366 | { |
1371 | char name[5 + 1 + 10 + 1]; | ||
1372 | |||
1373 | if (!cam || !cam->proc_entry) | 1367 | if (!cam || !cam->proc_entry) |
1374 | return; | 1368 | return; |
1375 | 1369 | ||
1376 | snprintf(name, sizeof(name), "video%d", cam->vdev.num); | 1370 | remove_proc_entry(video_device_node_name(&cam->vdev), cpia_proc_root); |
1377 | remove_proc_entry(name, cpia_proc_root); | ||
1378 | cam->proc_entry = NULL; | 1371 | cam->proc_entry = NULL; |
1379 | } | 1372 | } |
1380 | 1373 | ||
@@ -3999,7 +3992,7 @@ void cpia_unregister_camera(struct cam_data *cam) | |||
3999 | } | 3992 | } |
4000 | 3993 | ||
4001 | #ifdef CONFIG_PROC_FS | 3994 | #ifdef CONFIG_PROC_FS |
4002 | DBG("destroying /proc/cpia/video%d\n", cam->vdev.num); | 3995 | DBG("destroying /proc/cpia/%s\n", video_device_node_name(&cam->vdev)); |
4003 | destroy_proc_cpia_cam(cam); | 3996 | destroy_proc_cpia_cam(cam); |
4004 | #endif | 3997 | #endif |
4005 | if (!cam->open_count) { | 3998 | if (!cam->open_count) { |
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 0b4a8f309cf..6f91415eb7b 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
@@ -38,17 +38,12 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/videodev.h> | 40 | #include <linux/videodev.h> |
41 | #include <linux/stringify.h> | ||
41 | #include <media/v4l2-ioctl.h> | 42 | #include <media/v4l2-ioctl.h> |
42 | 43 | ||
43 | #include "cpia2.h" | 44 | #include "cpia2.h" |
44 | #include "cpia2dev.h" | 45 | #include "cpia2dev.h" |
45 | 46 | ||
46 | |||
47 | //#define _CPIA2_DEBUG_ | ||
48 | |||
49 | #define MAKE_STRING_1(x) #x | ||
50 | #define MAKE_STRING(x) MAKE_STRING_1(x) | ||
51 | |||
52 | static int video_nr = -1; | 47 | static int video_nr = -1; |
53 | module_param(video_nr, int, 0); | 48 | module_param(video_nr, int, 0); |
54 | MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)"); | 49 | MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)"); |
@@ -60,26 +55,26 @@ MODULE_PARM_DESC(buffer_size, "Size for each frame buffer in bytes (default 68k) | |||
60 | static int num_buffers = 3; | 55 | static int num_buffers = 3; |
61 | module_param(num_buffers, int, 0); | 56 | module_param(num_buffers, int, 0); |
62 | MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-" | 57 | MODULE_PARM_DESC(num_buffers, "Number of frame buffers (1-" |
63 | MAKE_STRING(VIDEO_MAX_FRAME) ", default 3)"); | 58 | __stringify(VIDEO_MAX_FRAME) ", default 3)"); |
64 | 59 | ||
65 | static int alternate = DEFAULT_ALT; | 60 | static int alternate = DEFAULT_ALT; |
66 | module_param(alternate, int, 0); | 61 | module_param(alternate, int, 0); |
67 | MODULE_PARM_DESC(alternate, "USB Alternate (" MAKE_STRING(USBIF_ISO_1) "-" | 62 | MODULE_PARM_DESC(alternate, "USB Alternate (" __stringify(USBIF_ISO_1) "-" |
68 | MAKE_STRING(USBIF_ISO_6) ", default " | 63 | __stringify(USBIF_ISO_6) ", default " |
69 | MAKE_STRING(DEFAULT_ALT) ")"); | 64 | __stringify(DEFAULT_ALT) ")"); |
70 | 65 | ||
71 | static int flicker_freq = 60; | 66 | static int flicker_freq = 60; |
72 | module_param(flicker_freq, int, 0); | 67 | module_param(flicker_freq, int, 0); |
73 | MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" MAKE_STRING(50) "or" | 68 | MODULE_PARM_DESC(flicker_freq, "Flicker frequency (" __stringify(50) "or" |
74 | MAKE_STRING(60) ", default " | 69 | __stringify(60) ", default " |
75 | MAKE_STRING(60) ")"); | 70 | __stringify(60) ")"); |
76 | 71 | ||
77 | static int flicker_mode = NEVER_FLICKER; | 72 | static int flicker_mode = NEVER_FLICKER; |
78 | module_param(flicker_mode, int, 0); | 73 | module_param(flicker_mode, int, 0); |
79 | MODULE_PARM_DESC(flicker_mode, | 74 | MODULE_PARM_DESC(flicker_mode, |
80 | "Flicker supression (" MAKE_STRING(NEVER_FLICKER) "or" | 75 | "Flicker supression (" __stringify(NEVER_FLICKER) "or" |
81 | MAKE_STRING(ANTI_FLICKER_ON) ", default " | 76 | __stringify(ANTI_FLICKER_ON) ", default " |
82 | MAKE_STRING(NEVER_FLICKER) ")"); | 77 | __stringify(NEVER_FLICKER) ")"); |
83 | 78 | ||
84 | MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>"); | 79 | MODULE_AUTHOR("Steve Miller (STMicroelectronics) <steve.miller@st.com>"); |
85 | MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); | 80 | MODULE_DESCRIPTION("V4L-driver for STMicroelectronics CPiA2 based cameras"); |
@@ -1926,7 +1921,6 @@ static const struct v4l2_file_operations fops_template = { | |||
1926 | static struct video_device cpia2_template = { | 1921 | static struct video_device cpia2_template = { |
1927 | /* I could not find any place for the old .initialize initializer?? */ | 1922 | /* I could not find any place for the old .initialize initializer?? */ |
1928 | .name= "CPiA2 Camera", | 1923 | .name= "CPiA2 Camera", |
1929 | .minor= -1, | ||
1930 | .fops= &fops_template, | 1924 | .fops= &fops_template, |
1931 | .release= video_device_release, | 1925 | .release= video_device_release, |
1932 | }; | 1926 | }; |
@@ -1967,9 +1961,9 @@ void cpia2_unregister_camera(struct camera_data *cam) | |||
1967 | if (!cam->open_count) { | 1961 | if (!cam->open_count) { |
1968 | video_unregister_device(cam->vdev); | 1962 | video_unregister_device(cam->vdev); |
1969 | } else { | 1963 | } else { |
1970 | LOG("/dev/video%d removed while open, " | 1964 | LOG("%s removed while open, deferring " |
1971 | "deferring video_unregister_device\n", | 1965 | "video_unregister_device\n", |
1972 | cam->vdev->num); | 1966 | video_device_node_name(cam->vdev)); |
1973 | } | 1967 | } |
1974 | } | 1968 | } |
1975 | 1969 | ||
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 4e278db31cc..c0885c69fd8 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
@@ -758,8 +758,8 @@ int cx18_v4l2_open(struct file *filp) | |||
758 | 758 | ||
759 | mutex_lock(&cx->serialize_lock); | 759 | mutex_lock(&cx->serialize_lock); |
760 | if (cx18_init_on_first_open(cx)) { | 760 | if (cx18_init_on_first_open(cx)) { |
761 | CX18_ERR("Failed to initialize on minor %d\n", | 761 | CX18_ERR("Failed to initialize on %s\n", |
762 | video_dev->minor); | 762 | video_device_node_name(video_dev)); |
763 | mutex_unlock(&cx->serialize_lock); | 763 | mutex_unlock(&cx->serialize_lock); |
764 | return -ENXIO; | 764 | return -ENXIO; |
765 | } | 765 | } |
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index c398651dd74..987a9308d93 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -219,6 +219,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) | |||
219 | { | 219 | { |
220 | struct cx18_stream *s = &cx->streams[type]; | 220 | struct cx18_stream *s = &cx->streams[type]; |
221 | int vfl_type = cx18_stream_info[type].vfl_type; | 221 | int vfl_type = cx18_stream_info[type].vfl_type; |
222 | const char *name; | ||
222 | int num, ret; | 223 | int num, ret; |
223 | 224 | ||
224 | /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? | 225 | /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? |
@@ -258,31 +259,30 @@ static int cx18_reg_dev(struct cx18 *cx, int type) | |||
258 | s->video_dev = NULL; | 259 | s->video_dev = NULL; |
259 | return ret; | 260 | return ret; |
260 | } | 261 | } |
261 | num = s->video_dev->num; | 262 | |
263 | name = video_device_node_name(s->video_dev); | ||
262 | 264 | ||
263 | switch (vfl_type) { | 265 | switch (vfl_type) { |
264 | case VFL_TYPE_GRABBER: | 266 | case VFL_TYPE_GRABBER: |
265 | CX18_INFO("Registered device video%d for %s " | 267 | CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n", |
266 | "(%d x %d.%02d kB)\n", | 268 | name, s->name, cx->stream_buffers[type], |
267 | num, s->name, cx->stream_buffers[type], | ||
268 | cx->stream_buf_size[type] / 1024, | 269 | cx->stream_buf_size[type] / 1024, |
269 | (cx->stream_buf_size[type] * 100 / 1024) % 100); | 270 | (cx->stream_buf_size[type] * 100 / 1024) % 100); |
270 | break; | 271 | break; |
271 | 272 | ||
272 | case VFL_TYPE_RADIO: | 273 | case VFL_TYPE_RADIO: |
273 | CX18_INFO("Registered device radio%d for %s\n", | 274 | CX18_INFO("Registered device %s for %s\n", name, s->name); |
274 | num, s->name); | ||
275 | break; | 275 | break; |
276 | 276 | ||
277 | case VFL_TYPE_VBI: | 277 | case VFL_TYPE_VBI: |
278 | if (cx->stream_buffers[type]) | 278 | if (cx->stream_buffers[type]) |
279 | CX18_INFO("Registered device vbi%d for %s " | 279 | CX18_INFO("Registered device %s for %s " |
280 | "(%d x %d bytes)\n", | 280 | "(%d x %d bytes)\n", |
281 | num, s->name, cx->stream_buffers[type], | 281 | name, s->name, cx->stream_buffers[type], |
282 | cx->stream_buf_size[type]); | 282 | cx->stream_buf_size[type]); |
283 | else | 283 | else |
284 | CX18_INFO("Registered device vbi%d for %s\n", | 284 | CX18_INFO("Registered device %s for %s\n", |
285 | num, s->name); | 285 | name, s->name); |
286 | break; | 286 | break; |
287 | } | 287 | } |
288 | 288 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 319c459459e..a5490823500 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c | |||
@@ -68,19 +68,19 @@ struct cx231xx_board cx231xx_boards[] = { | |||
68 | .type = CX231XX_VMUX_TELEVISION, | 68 | .type = CX231XX_VMUX_TELEVISION, |
69 | .vmux = CX231XX_VIN_3_1, | 69 | .vmux = CX231XX_VIN_3_1, |
70 | .amux = CX231XX_AMUX_VIDEO, | 70 | .amux = CX231XX_AMUX_VIDEO, |
71 | .gpio = 0, | 71 | .gpio = NULL, |
72 | }, { | 72 | }, { |
73 | .type = CX231XX_VMUX_COMPOSITE1, | 73 | .type = CX231XX_VMUX_COMPOSITE1, |
74 | .vmux = CX231XX_VIN_2_1, | 74 | .vmux = CX231XX_VIN_2_1, |
75 | .amux = CX231XX_AMUX_LINE_IN, | 75 | .amux = CX231XX_AMUX_LINE_IN, |
76 | .gpio = 0, | 76 | .gpio = NULL, |
77 | }, { | 77 | }, { |
78 | .type = CX231XX_VMUX_SVIDEO, | 78 | .type = CX231XX_VMUX_SVIDEO, |
79 | .vmux = CX231XX_VIN_1_1 | | 79 | .vmux = CX231XX_VIN_1_1 | |
80 | (CX231XX_VIN_1_2 << 8) | | 80 | (CX231XX_VIN_1_2 << 8) | |
81 | CX25840_SVIDEO_ON, | 81 | CX25840_SVIDEO_ON, |
82 | .amux = CX231XX_AMUX_LINE_IN, | 82 | .amux = CX231XX_AMUX_LINE_IN, |
83 | .gpio = 0, | 83 | .gpio = NULL, |
84 | } | 84 | } |
85 | }, | 85 | }, |
86 | }, | 86 | }, |
@@ -107,19 +107,19 @@ struct cx231xx_board cx231xx_boards[] = { | |||
107 | .type = CX231XX_VMUX_TELEVISION, | 107 | .type = CX231XX_VMUX_TELEVISION, |
108 | .vmux = CX231XX_VIN_3_1, | 108 | .vmux = CX231XX_VIN_3_1, |
109 | .amux = CX231XX_AMUX_VIDEO, | 109 | .amux = CX231XX_AMUX_VIDEO, |
110 | .gpio = 0, | 110 | .gpio = NULL, |
111 | }, { | 111 | }, { |
112 | .type = CX231XX_VMUX_COMPOSITE1, | 112 | .type = CX231XX_VMUX_COMPOSITE1, |
113 | .vmux = CX231XX_VIN_2_1, | 113 | .vmux = CX231XX_VIN_2_1, |
114 | .amux = CX231XX_AMUX_LINE_IN, | 114 | .amux = CX231XX_AMUX_LINE_IN, |
115 | .gpio = 0, | 115 | .gpio = NULL, |
116 | }, { | 116 | }, { |
117 | .type = CX231XX_VMUX_SVIDEO, | 117 | .type = CX231XX_VMUX_SVIDEO, |
118 | .vmux = CX231XX_VIN_1_1 | | 118 | .vmux = CX231XX_VIN_1_1 | |
119 | (CX231XX_VIN_1_2 << 8) | | 119 | (CX231XX_VIN_1_2 << 8) | |
120 | CX25840_SVIDEO_ON, | 120 | CX25840_SVIDEO_ON, |
121 | .amux = CX231XX_AMUX_LINE_IN, | 121 | .amux = CX231XX_AMUX_LINE_IN, |
122 | .gpio = 0, | 122 | .gpio = NULL, |
123 | } | 123 | } |
124 | }, | 124 | }, |
125 | }, | 125 | }, |
@@ -147,19 +147,19 @@ struct cx231xx_board cx231xx_boards[] = { | |||
147 | .type = CX231XX_VMUX_TELEVISION, | 147 | .type = CX231XX_VMUX_TELEVISION, |
148 | .vmux = CX231XX_VIN_3_1, | 148 | .vmux = CX231XX_VIN_3_1, |
149 | .amux = CX231XX_AMUX_VIDEO, | 149 | .amux = CX231XX_AMUX_VIDEO, |
150 | .gpio = 0, | 150 | .gpio = NULL, |
151 | }, { | 151 | }, { |
152 | .type = CX231XX_VMUX_COMPOSITE1, | 152 | .type = CX231XX_VMUX_COMPOSITE1, |
153 | .vmux = CX231XX_VIN_2_1, | 153 | .vmux = CX231XX_VIN_2_1, |
154 | .amux = CX231XX_AMUX_LINE_IN, | 154 | .amux = CX231XX_AMUX_LINE_IN, |
155 | .gpio = 0, | 155 | .gpio = NULL, |
156 | }, { | 156 | }, { |
157 | .type = CX231XX_VMUX_SVIDEO, | 157 | .type = CX231XX_VMUX_SVIDEO, |
158 | .vmux = CX231XX_VIN_1_1 | | 158 | .vmux = CX231XX_VIN_1_1 | |
159 | (CX231XX_VIN_1_2 << 8) | | 159 | (CX231XX_VIN_1_2 << 8) | |
160 | CX25840_SVIDEO_ON, | 160 | CX25840_SVIDEO_ON, |
161 | .amux = CX231XX_AMUX_LINE_IN, | 161 | .amux = CX231XX_AMUX_LINE_IN, |
162 | .gpio = 0, | 162 | .gpio = NULL, |
163 | } | 163 | } |
164 | }, | 164 | }, |
165 | }, | 165 | }, |
@@ -856,8 +856,9 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) | |||
856 | 856 | ||
857 | if (dev->users) { | 857 | if (dev->users) { |
858 | cx231xx_warn | 858 | cx231xx_warn |
859 | ("device /dev/video%d is open! Deregistration and memory " | 859 | ("device %s is open! Deregistration and memory " |
860 | "deallocation are deferred on close.\n", dev->vdev->num); | 860 | "deallocation are deferred on close.\n", |
861 | video_device_node_name(dev->vdev)); | ||
861 | 862 | ||
862 | dev->state |= DEV_MISCONFIGURED; | 863 | dev->state |= DEV_MISCONFIGURED; |
863 | cx231xx_uninit_isoc(dev); | 864 | cx231xx_uninit_isoc(dev); |
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c index 0d333e679f7..4a60dfbc347 100644 --- a/drivers/media/video/cx231xx/cx231xx-core.c +++ b/drivers/media/video/cx231xx/cx231xx-core.c | |||
@@ -66,32 +66,6 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | |||
66 | static LIST_HEAD(cx231xx_devlist); | 66 | static LIST_HEAD(cx231xx_devlist); |
67 | static DEFINE_MUTEX(cx231xx_devlist_mutex); | 67 | static DEFINE_MUTEX(cx231xx_devlist_mutex); |
68 | 68 | ||
69 | struct cx231xx *cx231xx_get_device(int minor, | ||
70 | enum v4l2_buf_type *fh_type, int *has_radio) | ||
71 | { | ||
72 | struct cx231xx *h, *dev = NULL; | ||
73 | |||
74 | *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
75 | *has_radio = 0; | ||
76 | |||
77 | mutex_lock(&cx231xx_devlist_mutex); | ||
78 | list_for_each_entry(h, &cx231xx_devlist, devlist) { | ||
79 | if (h->vdev->minor == minor) | ||
80 | dev = h; | ||
81 | if (h->vbi_dev->minor == minor) { | ||
82 | dev = h; | ||
83 | *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
84 | } | ||
85 | if (h->radio_dev && h->radio_dev->minor == minor) { | ||
86 | dev = h; | ||
87 | *has_radio = 1; | ||
88 | } | ||
89 | } | ||
90 | mutex_unlock(&cx231xx_devlist_mutex); | ||
91 | |||
92 | return dev; | ||
93 | } | ||
94 | |||
95 | /* | 69 | /* |
96 | * cx231xx_realease_resources() | 70 | * cx231xx_realease_resources() |
97 | * unregisters the v4l2,i2c and usb devices | 71 | * unregisters the v4l2,i2c and usb devices |
diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c index cd135f01b9c..15826f98b68 100644 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ b/drivers/media/video/cx231xx/cx231xx-input.c | |||
@@ -197,8 +197,7 @@ int cx231xx_ir_init(struct cx231xx *dev) | |||
197 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); | 197 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); |
198 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); | 198 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); |
199 | 199 | ||
200 | err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, | 200 | err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); |
201 | dev->board.ir_codes); | ||
202 | if (err < 0) | 201 | if (err < 0) |
203 | goto err_out_free; | 202 | goto err_out_free; |
204 | 203 | ||
@@ -217,7 +216,7 @@ int cx231xx_ir_init(struct cx231xx *dev) | |||
217 | cx231xx_ir_start(ir); | 216 | cx231xx_ir_start(ir); |
218 | 217 | ||
219 | /* all done */ | 218 | /* all done */ |
220 | err = input_register_device(ir->input); | 219 | err = ir_input_register(ir->input, dev->board.ir_codes); |
221 | if (err) | 220 | if (err) |
222 | goto err_out_stop; | 221 | goto err_out_stop; |
223 | 222 | ||
@@ -226,8 +225,6 @@ err_out_stop: | |||
226 | cx231xx_ir_stop(ir); | 225 | cx231xx_ir_stop(ir); |
227 | dev->ir = NULL; | 226 | dev->ir = NULL; |
228 | err_out_free: | 227 | err_out_free: |
229 | ir_input_free(input_dev); | ||
230 | input_free_device(input_dev); | ||
231 | kfree(ir); | 228 | kfree(ir); |
232 | return err; | 229 | return err; |
233 | } | 230 | } |
@@ -241,8 +238,7 @@ int cx231xx_ir_fini(struct cx231xx *dev) | |||
241 | return 0; | 238 | return 0; |
242 | 239 | ||
243 | cx231xx_ir_stop(ir); | 240 | cx231xx_ir_stop(ir); |
244 | ir_input_free(ir->input); | 241 | ir_input_unregister(ir->input); |
245 | input_unregister_device(ir->input); | ||
246 | kfree(ir); | 242 | kfree(ir); |
247 | 243 | ||
248 | /* done */ | 244 | /* done */ |
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index d095aa0d6d1..d4f546f11d7 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c | |||
@@ -1916,20 +1916,29 @@ static int radio_queryctrl(struct file *file, void *priv, | |||
1916 | */ | 1916 | */ |
1917 | static int cx231xx_v4l2_open(struct file *filp) | 1917 | static int cx231xx_v4l2_open(struct file *filp) |
1918 | { | 1918 | { |
1919 | int minor = video_devdata(filp)->minor; | ||
1920 | int errCode = 0, radio = 0; | 1919 | int errCode = 0, radio = 0; |
1921 | struct cx231xx *dev = NULL; | 1920 | struct video_device *vdev = video_devdata(filp); |
1921 | struct cx231xx *dev = video_drvdata(filp); | ||
1922 | struct cx231xx_fh *fh; | 1922 | struct cx231xx_fh *fh; |
1923 | enum v4l2_buf_type fh_type = 0; | 1923 | enum v4l2_buf_type fh_type = 0; |
1924 | 1924 | ||
1925 | dev = cx231xx_get_device(minor, &fh_type, &radio); | 1925 | switch (vdev->vfl_type) { |
1926 | if (NULL == dev) | 1926 | case VFL_TYPE_GRABBER: |
1927 | return -ENODEV; | 1927 | fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1928 | break; | ||
1929 | case VFL_TYPE_VBI: | ||
1930 | fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1931 | break; | ||
1932 | case VFL_TYPE_RADIO: | ||
1933 | radio = 1; | ||
1934 | break; | ||
1935 | } | ||
1928 | 1936 | ||
1929 | mutex_lock(&dev->lock); | 1937 | mutex_lock(&dev->lock); |
1930 | 1938 | ||
1931 | cx231xx_videodbg("open minor=%d type=%s users=%d\n", | 1939 | cx231xx_videodbg("open dev=%s type=%s users=%d\n", |
1932 | minor, v4l2_type_names[fh_type], dev->users); | 1940 | video_device_node_name(vdev), v4l2_type_names[fh_type], |
1941 | dev->users); | ||
1933 | 1942 | ||
1934 | #if 0 | 1943 | #if 0 |
1935 | errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); | 1944 | errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); |
@@ -2020,25 +2029,25 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) | |||
2020 | /*FIXME: I2C IR should be disconnected */ | 2029 | /*FIXME: I2C IR should be disconnected */ |
2021 | 2030 | ||
2022 | if (dev->radio_dev) { | 2031 | if (dev->radio_dev) { |
2023 | if (-1 != dev->radio_dev->minor) | 2032 | if (video_is_registered(dev->radio_dev)) |
2024 | video_unregister_device(dev->radio_dev); | 2033 | video_unregister_device(dev->radio_dev); |
2025 | else | 2034 | else |
2026 | video_device_release(dev->radio_dev); | 2035 | video_device_release(dev->radio_dev); |
2027 | dev->radio_dev = NULL; | 2036 | dev->radio_dev = NULL; |
2028 | } | 2037 | } |
2029 | if (dev->vbi_dev) { | 2038 | if (dev->vbi_dev) { |
2030 | cx231xx_info("V4L2 device /dev/vbi%d deregistered\n", | 2039 | cx231xx_info("V4L2 device %s deregistered\n", |
2031 | dev->vbi_dev->num); | 2040 | video_device_node_name(dev->vbi_dev)); |
2032 | if (-1 != dev->vbi_dev->minor) | 2041 | if (video_is_registered(dev->vbi_dev)) |
2033 | video_unregister_device(dev->vbi_dev); | 2042 | video_unregister_device(dev->vbi_dev); |
2034 | else | 2043 | else |
2035 | video_device_release(dev->vbi_dev); | 2044 | video_device_release(dev->vbi_dev); |
2036 | dev->vbi_dev = NULL; | 2045 | dev->vbi_dev = NULL; |
2037 | } | 2046 | } |
2038 | if (dev->vdev) { | 2047 | if (dev->vdev) { |
2039 | cx231xx_info("V4L2 device /dev/video%d deregistered\n", | 2048 | cx231xx_info("V4L2 device %s deregistered\n", |
2040 | dev->vdev->num); | 2049 | video_device_node_name(dev->vdev)); |
2041 | if (-1 != dev->vdev->minor) | 2050 | if (video_is_registered(dev->vdev)) |
2042 | video_unregister_device(dev->vdev); | 2051 | video_unregister_device(dev->vdev); |
2043 | else | 2052 | else |
2044 | video_device_release(dev->vdev); | 2053 | video_device_release(dev->vdev); |
@@ -2268,7 +2277,6 @@ static const struct video_device cx231xx_video_template = { | |||
2268 | .fops = &cx231xx_v4l_fops, | 2277 | .fops = &cx231xx_v4l_fops, |
2269 | .release = video_device_release, | 2278 | .release = video_device_release, |
2270 | .ioctl_ops = &video_ioctl_ops, | 2279 | .ioctl_ops = &video_ioctl_ops, |
2271 | .minor = -1, | ||
2272 | .tvnorms = V4L2_STD_ALL, | 2280 | .tvnorms = V4L2_STD_ALL, |
2273 | .current_norm = V4L2_STD_PAL, | 2281 | .current_norm = V4L2_STD_PAL, |
2274 | }; | 2282 | }; |
@@ -2303,7 +2311,6 @@ static struct video_device cx231xx_radio_template = { | |||
2303 | .name = "cx231xx-radio", | 2311 | .name = "cx231xx-radio", |
2304 | .fops = &radio_fops, | 2312 | .fops = &radio_fops, |
2305 | .ioctl_ops = &radio_ioctl_ops, | 2313 | .ioctl_ops = &radio_ioctl_ops, |
2306 | .minor = -1, | ||
2307 | }; | 2314 | }; |
2308 | 2315 | ||
2309 | /******************************** usb interface ******************************/ | 2316 | /******************************** usb interface ******************************/ |
@@ -2319,13 +2326,13 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, | |||
2319 | return NULL; | 2326 | return NULL; |
2320 | 2327 | ||
2321 | *vfd = *template; | 2328 | *vfd = *template; |
2322 | vfd->minor = -1; | ||
2323 | vfd->v4l2_dev = &dev->v4l2_dev; | 2329 | vfd->v4l2_dev = &dev->v4l2_dev; |
2324 | vfd->release = video_device_release; | 2330 | vfd->release = video_device_release; |
2325 | vfd->debug = video_debug; | 2331 | vfd->debug = video_debug; |
2326 | 2332 | ||
2327 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); | 2333 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); |
2328 | 2334 | ||
2335 | video_set_drvdata(vfd, dev); | ||
2329 | return vfd; | 2336 | return vfd; |
2330 | } | 2337 | } |
2331 | 2338 | ||
@@ -2374,8 +2381,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2374 | return ret; | 2381 | return ret; |
2375 | } | 2382 | } |
2376 | 2383 | ||
2377 | cx231xx_info("%s/0: registered device video%d [v4l2]\n", | 2384 | cx231xx_info("%s/0: registered device %s [v4l2]\n", |
2378 | dev->name, dev->vdev->num); | 2385 | dev->name, video_device_node_name(dev->vdev)); |
2379 | 2386 | ||
2380 | /* Initialize VBI template */ | 2387 | /* Initialize VBI template */ |
2381 | memcpy(&cx231xx_vbi_template, &cx231xx_video_template, | 2388 | memcpy(&cx231xx_vbi_template, &cx231xx_video_template, |
@@ -2393,8 +2400,8 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2393 | return ret; | 2400 | return ret; |
2394 | } | 2401 | } |
2395 | 2402 | ||
2396 | cx231xx_info("%s/0: registered device vbi%d\n", | 2403 | cx231xx_info("%s/0: registered device %s\n", |
2397 | dev->name, dev->vbi_dev->num); | 2404 | dev->name, video_device_node_name(dev->vbi_dev)); |
2398 | 2405 | ||
2399 | if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { | 2406 | if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { |
2400 | dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, | 2407 | dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, |
@@ -2409,12 +2416,13 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2409 | cx231xx_errdev("can't register radio device\n"); | 2416 | cx231xx_errdev("can't register radio device\n"); |
2410 | return ret; | 2417 | return ret; |
2411 | } | 2418 | } |
2412 | cx231xx_info("Registered radio device as /dev/radio%d\n", | 2419 | cx231xx_info("Registered radio device as %s\n", |
2413 | dev->radio_dev->num); | 2420 | video_device_node_name(dev->radio_dev)); |
2414 | } | 2421 | } |
2415 | 2422 | ||
2416 | cx231xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", | 2423 | cx231xx_info("V4L2 device registered as %s and %s\n", |
2417 | dev->vdev->num, dev->vbi_dev->num); | 2424 | video_device_node_name(dev->vdev), |
2425 | video_device_node_name(dev->vbi_dev)); | ||
2418 | 2426 | ||
2419 | return 0; | 2427 | return 0; |
2420 | } | 2428 | } |
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h index 64e2ddd3c40..17d4d1a800c 100644 --- a/drivers/media/video/cx231xx/cx231xx.h +++ b/drivers/media/video/cx231xx/cx231xx.h | |||
@@ -689,8 +689,6 @@ void cx231xx_release_analog_resources(struct cx231xx *dev); | |||
689 | int cx231xx_register_analog_devices(struct cx231xx *dev); | 689 | int cx231xx_register_analog_devices(struct cx231xx *dev); |
690 | void cx231xx_remove_from_devlist(struct cx231xx *dev); | 690 | void cx231xx_remove_from_devlist(struct cx231xx *dev); |
691 | void cx231xx_add_into_devlist(struct cx231xx *dev); | 691 | void cx231xx_add_into_devlist(struct cx231xx *dev); |
692 | struct cx231xx *cx231xx_get_device(int minor, | ||
693 | enum v4l2_buf_type *fh_type, int *has_radio); | ||
694 | void cx231xx_init_extension(struct cx231xx *dev); | 692 | void cx231xx_init_extension(struct cx231xx *dev); |
695 | void cx231xx_close_extension(struct cx231xx *dev); | 693 | void cx231xx_close_extension(struct cx231xx *dev); |
696 | 694 | ||
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c index c04222ffb28..d4a9d2c5947 100644 --- a/drivers/media/video/cx23885/cimax2.c +++ b/drivers/media/video/cx23885/cimax2.c | |||
@@ -53,6 +53,8 @@ | |||
53 | #define NETUP_CI_CTL 0x04 | 53 | #define NETUP_CI_CTL 0x04 |
54 | #define NETUP_CI_RD 1 | 54 | #define NETUP_CI_RD 1 |
55 | 55 | ||
56 | #define NETUP_IRQ_DETAM 0x1 | ||
57 | #define NETUP_IRQ_IRQAM 0x4 | ||
56 | 58 | ||
57 | static unsigned int ci_dbg; | 59 | static unsigned int ci_dbg; |
58 | module_param(ci_dbg, int, 0644); | 60 | module_param(ci_dbg, int, 0644); |
@@ -73,6 +75,9 @@ struct netup_ci_state { | |||
73 | int status; | 75 | int status; |
74 | struct work_struct work; | 76 | struct work_struct work; |
75 | void *priv; | 77 | void *priv; |
78 | u8 current_irq_mode; | ||
79 | int current_ci_flag; | ||
80 | unsigned long next_status_checked_time; | ||
76 | }; | 81 | }; |
77 | 82 | ||
78 | 83 | ||
@@ -169,24 +174,26 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, | |||
169 | if (0 != slot) | 174 | if (0 != slot) |
170 | return -EINVAL; | 175 | return -EINVAL; |
171 | 176 | ||
172 | ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, | 177 | if (state->current_ci_flag != flag) { |
173 | 0, &store, 1); | 178 | ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, |
174 | if (ret != 0) | 179 | 0, &store, 1); |
175 | return ret; | 180 | if (ret != 0) |
181 | return ret; | ||
176 | 182 | ||
177 | store &= ~0x0c; | 183 | store &= ~0x0c; |
178 | store |= flag; | 184 | store |= flag; |
179 | 185 | ||
180 | ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, | 186 | ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, |
181 | 0, &store, 1); | 187 | 0, &store, 1); |
182 | if (ret != 0) | 188 | if (ret != 0) |
183 | return ret; | 189 | return ret; |
190 | }; | ||
191 | state->current_ci_flag = flag; | ||
184 | 192 | ||
185 | mutex_lock(&dev->gpio_lock); | 193 | mutex_lock(&dev->gpio_lock); |
186 | 194 | ||
187 | /* write addr */ | 195 | /* write addr */ |
188 | cx_write(MC417_OEN, NETUP_EN_ALL); | 196 | cx_write(MC417_OEN, NETUP_EN_ALL); |
189 | msleep(2); | ||
190 | cx_write(MC417_RWD, NETUP_CTRL_OFF | | 197 | cx_write(MC417_RWD, NETUP_CTRL_OFF | |
191 | NETUP_ADLO | (0xff & addr)); | 198 | NETUP_ADLO | (0xff & addr)); |
192 | cx_clear(MC417_RWD, NETUP_ADLO); | 199 | cx_clear(MC417_RWD, NETUP_ADLO); |
@@ -196,7 +203,6 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, | |||
196 | 203 | ||
197 | if (read) { /* data in */ | 204 | if (read) { /* data in */ |
198 | cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA); | 205 | cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA); |
199 | msleep(2); | ||
200 | } else /* data out */ | 206 | } else /* data out */ |
201 | cx_write(MC417_RWD, NETUP_CTRL_OFF | data); | 207 | cx_write(MC417_RWD, NETUP_CTRL_OFF | data); |
202 | 208 | ||
@@ -213,8 +219,8 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, | |||
213 | if (mem < 0) | 219 | if (mem < 0) |
214 | return -EREMOTEIO; | 220 | return -EREMOTEIO; |
215 | 221 | ||
216 | ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__, | 222 | ci_dbg_print("%s: %s: chipaddr=[0x%x] addr=[0x%02x], %s=%x\n", __func__, |
217 | (read) ? "read" : "write", addr, | 223 | (read) ? "read" : "write", state->ci_i2c_addr, addr, |
218 | (flag == NETUP_CI_CTL) ? "ctl" : "mem", | 224 | (flag == NETUP_CI_CTL) ? "ctl" : "mem", |
219 | (read) ? mem : data); | 225 | (read) ? mem : data); |
220 | 226 | ||
@@ -283,14 +289,39 @@ int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot) | |||
283 | return 0; | 289 | return 0; |
284 | } | 290 | } |
285 | 291 | ||
292 | int netup_ci_set_irq(struct dvb_ca_en50221 *en50221, u8 irq_mode) | ||
293 | { | ||
294 | struct netup_ci_state *state = en50221->data; | ||
295 | int ret; | ||
296 | |||
297 | if (irq_mode == state->current_irq_mode) | ||
298 | return 0; | ||
299 | |||
300 | ci_dbg_print("%s: chipaddr=[0x%x] setting ci IRQ to [0x%x] \n", | ||
301 | __func__, state->ci_i2c_addr, irq_mode); | ||
302 | ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, | ||
303 | 0x1b, &irq_mode, 1); | ||
304 | |||
305 | if (ret != 0) | ||
306 | return ret; | ||
307 | |||
308 | state->current_irq_mode = irq_mode; | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
286 | int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot) | 313 | int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot) |
287 | { | 314 | { |
288 | struct netup_ci_state *state = en50221->data; | 315 | struct netup_ci_state *state = en50221->data; |
289 | u8 buf = 0x60; | 316 | u8 buf; |
290 | 317 | ||
291 | if (0 != slot) | 318 | if (0 != slot) |
292 | return -EINVAL; | 319 | return -EINVAL; |
293 | 320 | ||
321 | netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, | ||
322 | 0, &buf, 1); | ||
323 | buf |= 0x60; | ||
324 | |||
294 | return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, | 325 | return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, |
295 | 0, &buf, 1); | 326 | 0, &buf, 1); |
296 | } | 327 | } |
@@ -303,21 +334,35 @@ static void netup_read_ci_status(struct work_struct *work) | |||
303 | u8 buf[33]; | 334 | u8 buf[33]; |
304 | int ret; | 335 | int ret; |
305 | 336 | ||
306 | ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, | 337 | /* CAM module IRQ processing. fast operation */ |
307 | 0, &buf[0], 33); | 338 | dvb_ca_en50221_frda_irq(&state->ca, 0); |
308 | 339 | ||
309 | if (ret != 0) | 340 | /* CAM module INSERT/REMOVE processing. slow operation because of i2c |
310 | return; | 341 | * transfers */ |
342 | if (time_after(jiffies, state->next_status_checked_time) | ||
343 | || !state->status) { | ||
344 | ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, | ||
345 | 0, &buf[0], 33); | ||
346 | |||
347 | state->next_status_checked_time = jiffies | ||
348 | + msecs_to_jiffies(1000); | ||
349 | |||
350 | if (ret != 0) | ||
351 | return; | ||
311 | 352 | ||
312 | ci_dbg_print("%s: Slot Status Addr=[0x%04x], Reg=[0x%02x], data=%02x, " | 353 | ci_dbg_print("%s: Slot Status Addr=[0x%04x], " |
313 | "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0], | 354 | "Reg=[0x%02x], data=%02x, " |
314 | buf[32]); | 355 | "TS config = %02x\n", __func__, |
356 | state->ci_i2c_addr, 0, buf[0], | ||
357 | buf[0]); | ||
315 | 358 | ||
316 | if (buf[0] & 1) | 359 | |
317 | state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | | 360 | if (buf[0] & 1) |
318 | DVB_CA_EN50221_POLL_CAM_READY; | 361 | state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | |
319 | else | 362 | DVB_CA_EN50221_POLL_CAM_READY; |
320 | state->status = 0; | 363 | else |
364 | state->status = 0; | ||
365 | }; | ||
321 | } | 366 | } |
322 | 367 | ||
323 | /* CI irq handler */ | 368 | /* CI irq handler */ |
@@ -347,6 +392,9 @@ int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open | |||
347 | if (0 != slot) | 392 | if (0 != slot) |
348 | return -EINVAL; | 393 | return -EINVAL; |
349 | 394 | ||
395 | netup_ci_set_irq(en50221, open ? (NETUP_IRQ_DETAM | NETUP_IRQ_IRQAM) | ||
396 | : NETUP_IRQ_DETAM); | ||
397 | |||
350 | return state->status; | 398 | return state->status; |
351 | } | 399 | } |
352 | 400 | ||
@@ -381,8 +429,8 @@ int netup_ci_init(struct cx23885_tsport *port) | |||
381 | 0x01, /* power on (use it like store place) */ | 429 | 0x01, /* power on (use it like store place) */ |
382 | 0x00, /* RFU */ | 430 | 0x00, /* RFU */ |
383 | 0x00, /* int status read only */ | 431 | 0x00, /* int status read only */ |
384 | 0x01, /* all int unmasked */ | 432 | NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM, /* DETAM, IRQAM unmasked */ |
385 | 0x04, /* int config */ | 433 | 0x05, /* EXTINT=active-high, INT=push-pull */ |
386 | 0x00, /* USCG1 */ | 434 | 0x00, /* USCG1 */ |
387 | 0x04, /* ack active low */ | 435 | 0x04, /* ack active low */ |
388 | 0x00, /* LOCK = 0 */ | 436 | 0x00, /* LOCK = 0 */ |
@@ -422,6 +470,7 @@ int netup_ci_init(struct cx23885_tsport *port) | |||
422 | state->ca.poll_slot_status = netup_poll_ci_slot_status; | 470 | state->ca.poll_slot_status = netup_poll_ci_slot_status; |
423 | state->ca.data = state; | 471 | state->ca.data = state; |
424 | state->priv = port; | 472 | state->priv = port; |
473 | state->current_irq_mode = NETUP_IRQ_IRQAM | NETUP_IRQ_DETAM; | ||
425 | 474 | ||
426 | ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, | 475 | ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, |
427 | 0, &cimax_init[0], 34); | 476 | 0, &cimax_init[0], 34); |
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 0eed852c61e..88c0d248111 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c | |||
@@ -1568,28 +1568,11 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
1568 | 1568 | ||
1569 | static int mpeg_open(struct file *file) | 1569 | static int mpeg_open(struct file *file) |
1570 | { | 1570 | { |
1571 | int minor = video_devdata(file)->minor; | 1571 | struct cx23885_dev *dev = video_drvdata(file); |
1572 | struct cx23885_dev *h, *dev = NULL; | ||
1573 | struct list_head *list; | ||
1574 | struct cx23885_fh *fh; | 1572 | struct cx23885_fh *fh; |
1575 | 1573 | ||
1576 | dprintk(2, "%s()\n", __func__); | 1574 | dprintk(2, "%s()\n", __func__); |
1577 | 1575 | ||
1578 | lock_kernel(); | ||
1579 | list_for_each(list, &cx23885_devlist) { | ||
1580 | h = list_entry(list, struct cx23885_dev, devlist); | ||
1581 | if (h->v4l_device && | ||
1582 | h->v4l_device->minor == minor) { | ||
1583 | dev = h; | ||
1584 | break; | ||
1585 | } | ||
1586 | } | ||
1587 | |||
1588 | if (dev == NULL) { | ||
1589 | unlock_kernel(); | ||
1590 | return -ENODEV; | ||
1591 | } | ||
1592 | |||
1593 | /* allocate + initialize per filehandle data */ | 1576 | /* allocate + initialize per filehandle data */ |
1594 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 1577 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
1595 | if (NULL == fh) { | 1578 | if (NULL == fh) { |
@@ -1597,6 +1580,8 @@ static int mpeg_open(struct file *file) | |||
1597 | return -ENOMEM; | 1580 | return -ENOMEM; |
1598 | } | 1581 | } |
1599 | 1582 | ||
1583 | lock_kernel(); | ||
1584 | |||
1600 | file->private_data = fh; | 1585 | file->private_data = fh; |
1601 | fh->dev = dev; | 1586 | fh->dev = dev; |
1602 | 1587 | ||
@@ -1736,7 +1721,6 @@ static struct video_device cx23885_mpeg_template = { | |||
1736 | .name = "cx23885", | 1721 | .name = "cx23885", |
1737 | .fops = &mpeg_fops, | 1722 | .fops = &mpeg_fops, |
1738 | .ioctl_ops = &mpeg_ioctl_ops, | 1723 | .ioctl_ops = &mpeg_ioctl_ops, |
1739 | .minor = -1, | ||
1740 | .tvnorms = CX23885_NORMS, | 1724 | .tvnorms = CX23885_NORMS, |
1741 | .current_norm = V4L2_STD_NTSC_M, | 1725 | .current_norm = V4L2_STD_NTSC_M, |
1742 | }; | 1726 | }; |
@@ -1746,7 +1730,7 @@ void cx23885_417_unregister(struct cx23885_dev *dev) | |||
1746 | dprintk(1, "%s()\n", __func__); | 1730 | dprintk(1, "%s()\n", __func__); |
1747 | 1731 | ||
1748 | if (dev->v4l_device) { | 1732 | if (dev->v4l_device) { |
1749 | if (-1 != dev->v4l_device->minor) | 1733 | if (video_is_registered(dev->v4l_device)) |
1750 | video_unregister_device(dev->v4l_device); | 1734 | video_unregister_device(dev->v4l_device); |
1751 | else | 1735 | else |
1752 | video_device_release(dev->v4l_device); | 1736 | video_device_release(dev->v4l_device); |
@@ -1803,6 +1787,7 @@ int cx23885_417_register(struct cx23885_dev *dev) | |||
1803 | /* Allocate and initialize V4L video device */ | 1787 | /* Allocate and initialize V4L video device */ |
1804 | dev->v4l_device = cx23885_video_dev_alloc(tsport, | 1788 | dev->v4l_device = cx23885_video_dev_alloc(tsport, |
1805 | dev->pci, &cx23885_mpeg_template, "mpeg"); | 1789 | dev->pci, &cx23885_mpeg_template, "mpeg"); |
1790 | video_set_drvdata(dev->v4l_device, dev); | ||
1806 | err = video_register_device(dev->v4l_device, | 1791 | err = video_register_device(dev->v4l_device, |
1807 | VFL_TYPE_GRABBER, -1); | 1792 | VFL_TYPE_GRABBER, -1); |
1808 | if (err < 0) { | 1793 | if (err < 0) { |
@@ -1810,8 +1795,8 @@ int cx23885_417_register(struct cx23885_dev *dev) | |||
1810 | return err; | 1795 | return err; |
1811 | } | 1796 | } |
1812 | 1797 | ||
1813 | printk(KERN_INFO "%s: registered device video%d [mpeg]\n", | 1798 | printk(KERN_INFO "%s: registered device %s [mpeg]\n", |
1814 | dev->name, dev->v4l_device->num); | 1799 | dev->name, video_device_node_name(dev->v4l_device)); |
1815 | 1800 | ||
1816 | return 0; | 1801 | return 0; |
1817 | } | 1802 | } |
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 04b12d27bc1..0dde57e96d3 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c | |||
@@ -55,9 +55,6 @@ MODULE_PARM_DESC(card, "card type"); | |||
55 | 55 | ||
56 | static unsigned int cx23885_devcount; | 56 | static unsigned int cx23885_devcount; |
57 | 57 | ||
58 | static DEFINE_MUTEX(devlist); | ||
59 | LIST_HEAD(cx23885_devlist); | ||
60 | |||
61 | #define NO_SYNC_LINE (-1U) | 58 | #define NO_SYNC_LINE (-1U) |
62 | 59 | ||
63 | /* FIXME, these allocations will change when | 60 | /* FIXME, these allocations will change when |
@@ -785,10 +782,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
785 | dev->nr = cx23885_devcount++; | 782 | dev->nr = cx23885_devcount++; |
786 | sprintf(dev->name, "cx23885[%d]", dev->nr); | 783 | sprintf(dev->name, "cx23885[%d]", dev->nr); |
787 | 784 | ||
788 | mutex_lock(&devlist); | ||
789 | list_add_tail(&dev->devlist, &cx23885_devlist); | ||
790 | mutex_unlock(&devlist); | ||
791 | |||
792 | /* Configure the internal memory */ | 785 | /* Configure the internal memory */ |
793 | if (dev->pci->device == 0x8880) { | 786 | if (dev->pci->device == 0x8880) { |
794 | /* Could be 887 or 888, assume a default */ | 787 | /* Could be 887 or 888, assume a default */ |
@@ -2008,10 +2001,6 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev) | |||
2008 | /* unregister stuff */ | 2001 | /* unregister stuff */ |
2009 | free_irq(pci_dev->irq, dev); | 2002 | free_irq(pci_dev->irq, dev); |
2010 | 2003 | ||
2011 | mutex_lock(&devlist); | ||
2012 | list_del(&dev->devlist); | ||
2013 | mutex_unlock(&devlist); | ||
2014 | |||
2015 | cx23885_dev_unregister(dev); | 2004 | cx23885_dev_unregister(dev); |
2016 | v4l2_device_unregister(v4l2_dev); | 2005 | v4l2_device_unregister(v4l2_dev); |
2017 | kfree(dev); | 2006 | kfree(dev); |
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index 469e083dd5f..768eec92ccf 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c | |||
@@ -377,7 +377,7 @@ int cx23885_input_init(struct cx23885_dev *dev) | |||
377 | cx23885_boards[dev->board].name); | 377 | cx23885_boards[dev->board].name); |
378 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci)); | 378 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci)); |
379 | 379 | ||
380 | ret = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); | 380 | ret = ir_input_init(input_dev, &ir->ir, ir_type); |
381 | if (ret < 0) | 381 | if (ret < 0) |
382 | goto err_out_free; | 382 | goto err_out_free; |
383 | 383 | ||
@@ -397,7 +397,7 @@ int cx23885_input_init(struct cx23885_dev *dev) | |||
397 | dev->ir_input = ir; | 397 | dev->ir_input = ir; |
398 | cx23885_input_ir_start(dev); | 398 | cx23885_input_ir_start(dev); |
399 | 399 | ||
400 | ret = input_register_device(ir->dev); | 400 | ret = ir_input_register(ir->dev, ir_codes); |
401 | if (ret) | 401 | if (ret) |
402 | goto err_out_stop; | 402 | goto err_out_stop; |
403 | 403 | ||
@@ -407,8 +407,6 @@ err_out_stop: | |||
407 | cx23885_input_ir_stop(dev); | 407 | cx23885_input_ir_stop(dev); |
408 | dev->ir_input = NULL; | 408 | dev->ir_input = NULL; |
409 | err_out_free: | 409 | err_out_free: |
410 | ir_input_free(input_dev); | ||
411 | input_free_device(input_dev); | ||
412 | kfree(ir); | 410 | kfree(ir); |
413 | return ret; | 411 | return ret; |
414 | } | 412 | } |
@@ -420,8 +418,7 @@ void cx23885_input_fini(struct cx23885_dev *dev) | |||
420 | 418 | ||
421 | if (dev->ir_input == NULL) | 419 | if (dev->ir_input == NULL) |
422 | return; | 420 | return; |
423 | ir_input_free(dev->ir_input->dev); | 421 | ir_input_unregister(dev->ir_input->dev); |
424 | input_unregister_device(dev->ir_input->dev); | ||
425 | kfree(dev->ir_input); | 422 | kfree(dev->ir_input); |
426 | dev->ir_input = NULL; | 423 | dev->ir_input = NULL; |
427 | } | 424 | } |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 8b372b4f0de..8934d61cf66 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -318,11 +318,11 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, | |||
318 | if (NULL == vfd) | 318 | if (NULL == vfd) |
319 | return NULL; | 319 | return NULL; |
320 | *vfd = *template; | 320 | *vfd = *template; |
321 | vfd->minor = -1; | ||
322 | vfd->v4l2_dev = &dev->v4l2_dev; | 321 | vfd->v4l2_dev = &dev->v4l2_dev; |
323 | vfd->release = video_device_release; | 322 | vfd->release = video_device_release; |
324 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", | 323 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", |
325 | dev->name, type, cx23885_boards[dev->board].name); | 324 | dev->name, type, cx23885_boards[dev->board].name); |
325 | video_set_drvdata(vfd, dev); | ||
326 | return vfd; | 326 | return vfd; |
327 | } | 327 | } |
328 | 328 | ||
@@ -716,46 +716,34 @@ static int get_resource(struct cx23885_fh *fh) | |||
716 | 716 | ||
717 | static int video_open(struct file *file) | 717 | static int video_open(struct file *file) |
718 | { | 718 | { |
719 | int minor = video_devdata(file)->minor; | 719 | struct video_device *vdev = video_devdata(file); |
720 | struct cx23885_dev *h, *dev = NULL; | 720 | struct cx23885_dev *dev = video_drvdata(file); |
721 | struct cx23885_fh *fh; | 721 | struct cx23885_fh *fh; |
722 | struct list_head *list; | ||
723 | enum v4l2_buf_type type = 0; | 722 | enum v4l2_buf_type type = 0; |
724 | int radio = 0; | 723 | int radio = 0; |
725 | 724 | ||
726 | lock_kernel(); | 725 | switch (vdev->vfl_type) { |
727 | list_for_each(list, &cx23885_devlist) { | 726 | case VFL_TYPE_GRABBER: |
728 | h = list_entry(list, struct cx23885_dev, devlist); | 727 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
729 | if (h->video_dev && | 728 | break; |
730 | h->video_dev->minor == minor) { | 729 | case VFL_TYPE_VBI: |
731 | dev = h; | 730 | type = V4L2_BUF_TYPE_VBI_CAPTURE; |
732 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 731 | break; |
733 | } | 732 | case VFL_TYPE_RADIO: |
734 | if (h->vbi_dev && | 733 | radio = 1; |
735 | h->vbi_dev->minor == minor) { | 734 | break; |
736 | dev = h; | ||
737 | type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
738 | } | ||
739 | if (h->radio_dev && | ||
740 | h->radio_dev->minor == minor) { | ||
741 | radio = 1; | ||
742 | dev = h; | ||
743 | } | ||
744 | } | ||
745 | if (NULL == dev) { | ||
746 | unlock_kernel(); | ||
747 | return -ENODEV; | ||
748 | } | 735 | } |
749 | 736 | ||
750 | dprintk(1, "open minor=%d radio=%d type=%s\n", | 737 | dprintk(1, "open dev=%s radio=%d type=%s\n", |
751 | minor, radio, v4l2_type_names[type]); | 738 | video_device_node_name(vdev), radio, v4l2_type_names[type]); |
752 | 739 | ||
753 | /* allocate + initialize per filehandle data */ | 740 | /* allocate + initialize per filehandle data */ |
754 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 741 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
755 | if (NULL == fh) { | 742 | if (NULL == fh) |
756 | unlock_kernel(); | ||
757 | return -ENOMEM; | 743 | return -ENOMEM; |
758 | } | 744 | |
745 | lock_kernel(); | ||
746 | |||
759 | file->private_data = fh; | 747 | file->private_data = fh; |
760 | fh->dev = dev; | 748 | fh->dev = dev; |
761 | fh->radio = radio; | 749 | fh->radio = radio; |
@@ -1441,7 +1429,6 @@ static struct video_device cx23885_vbi_template; | |||
1441 | static struct video_device cx23885_video_template = { | 1429 | static struct video_device cx23885_video_template = { |
1442 | .name = "cx23885-video", | 1430 | .name = "cx23885-video", |
1443 | .fops = &video_fops, | 1431 | .fops = &video_fops, |
1444 | .minor = -1, | ||
1445 | .ioctl_ops = &video_ioctl_ops, | 1432 | .ioctl_ops = &video_ioctl_ops, |
1446 | .tvnorms = CX23885_NORMS, | 1433 | .tvnorms = CX23885_NORMS, |
1447 | .current_norm = V4L2_STD_NTSC_M, | 1434 | .current_norm = V4L2_STD_NTSC_M, |
@@ -1461,7 +1448,7 @@ void cx23885_video_unregister(struct cx23885_dev *dev) | |||
1461 | cx_clear(PCI_INT_MSK, 1); | 1448 | cx_clear(PCI_INT_MSK, 1); |
1462 | 1449 | ||
1463 | if (dev->video_dev) { | 1450 | if (dev->video_dev) { |
1464 | if (-1 != dev->video_dev->minor) | 1451 | if (video_is_registered(dev->video_dev)) |
1465 | video_unregister_device(dev->video_dev); | 1452 | video_unregister_device(dev->video_dev); |
1466 | else | 1453 | else |
1467 | video_device_release(dev->video_dev); | 1454 | video_device_release(dev->video_dev); |
@@ -1532,8 +1519,8 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1532 | dev->name); | 1519 | dev->name); |
1533 | goto fail_unreg; | 1520 | goto fail_unreg; |
1534 | } | 1521 | } |
1535 | printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n", | 1522 | printk(KERN_INFO "%s/0: registered device %s [v4l2]\n", |
1536 | dev->name, dev->video_dev->num); | 1523 | dev->name, video_device_node_name(dev->video_dev)); |
1537 | /* initial device configuration */ | 1524 | /* initial device configuration */ |
1538 | mutex_lock(&dev->lock); | 1525 | mutex_lock(&dev->lock); |
1539 | cx23885_set_tvnorm(dev, dev->tvnorm); | 1526 | cx23885_set_tvnorm(dev, dev->tvnorm); |
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index fa744764dc8..08b3f6b136a 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h | |||
@@ -303,7 +303,6 @@ struct cx23885_tsport { | |||
303 | }; | 303 | }; |
304 | 304 | ||
305 | struct cx23885_dev { | 305 | struct cx23885_dev { |
306 | struct list_head devlist; | ||
307 | atomic_t refcount; | 306 | atomic_t refcount; |
308 | struct v4l2_device v4l2_dev; | 307 | struct v4l2_device v4l2_dev; |
309 | 308 | ||
@@ -399,8 +398,6 @@ static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev) | |||
399 | 398 | ||
400 | extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw); | 399 | extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw); |
401 | 400 | ||
402 | extern struct list_head cx23885_devlist; | ||
403 | |||
404 | #define SRAM_CH01 0 /* Video A */ | 401 | #define SRAM_CH01 0 /* Video A */ |
405 | #define SRAM_CH02 1 /* VBI A */ | 402 | #define SRAM_CH02 1 /* VBI A */ |
406 | #define SRAM_CH03 2 /* Video B */ | 403 | #define SRAM_CH03 2 /* Video B */ |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index fbdc1cde56a..6fe30e6c426 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -1048,21 +1048,15 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) | |||
1048 | 1048 | ||
1049 | static int mpeg_open(struct file *file) | 1049 | static int mpeg_open(struct file *file) |
1050 | { | 1050 | { |
1051 | int minor = video_devdata(file)->minor; | 1051 | struct video_device *vdev = video_devdata(file); |
1052 | struct cx8802_dev *dev = NULL; | 1052 | struct cx8802_dev *dev = video_drvdata(file); |
1053 | struct cx8802_fh *fh; | 1053 | struct cx8802_fh *fh; |
1054 | struct cx8802_driver *drv = NULL; | 1054 | struct cx8802_driver *drv = NULL; |
1055 | int err; | 1055 | int err; |
1056 | 1056 | ||
1057 | lock_kernel(); | ||
1058 | dev = cx8802_get_device(minor); | ||
1059 | |||
1060 | dprintk( 1, "%s\n", __func__); | 1057 | dprintk( 1, "%s\n", __func__); |
1061 | 1058 | ||
1062 | if (dev == NULL) { | 1059 | lock_kernel(); |
1063 | unlock_kernel(); | ||
1064 | return -ENODEV; | ||
1065 | } | ||
1066 | 1060 | ||
1067 | /* Make sure we can acquire the hardware */ | 1061 | /* Make sure we can acquire the hardware */ |
1068 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); | 1062 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); |
@@ -1081,7 +1075,7 @@ static int mpeg_open(struct file *file) | |||
1081 | unlock_kernel(); | 1075 | unlock_kernel(); |
1082 | return -EINVAL; | 1076 | return -EINVAL; |
1083 | } | 1077 | } |
1084 | dprintk(1,"open minor=%d\n",minor); | 1078 | dprintk(1, "open dev=%s\n", video_device_node_name(vdev)); |
1085 | 1079 | ||
1086 | /* allocate + initialize per filehandle data */ | 1080 | /* allocate + initialize per filehandle data */ |
1087 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); | 1081 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); |
@@ -1129,10 +1123,6 @@ static int mpeg_release(struct file *file) | |||
1129 | kfree(fh); | 1123 | kfree(fh); |
1130 | 1124 | ||
1131 | /* Make sure we release the hardware */ | 1125 | /* Make sure we release the hardware */ |
1132 | dev = cx8802_get_device(video_devdata(file)->minor); | ||
1133 | if (dev == NULL) | ||
1134 | return -ENODEV; | ||
1135 | |||
1136 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); | 1126 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); |
1137 | if (drv) | 1127 | if (drv) |
1138 | drv->request_release(drv); | 1128 | drv->request_release(drv); |
@@ -1220,7 +1210,6 @@ static struct video_device cx8802_mpeg_template = { | |||
1220 | .name = "cx8802", | 1210 | .name = "cx8802", |
1221 | .fops = &mpeg_fops, | 1211 | .fops = &mpeg_fops, |
1222 | .ioctl_ops = &mpeg_ioctl_ops, | 1212 | .ioctl_ops = &mpeg_ioctl_ops, |
1223 | .minor = -1, | ||
1224 | .tvnorms = CX88_NORMS, | 1213 | .tvnorms = CX88_NORMS, |
1225 | .current_norm = V4L2_STD_NTSC_M, | 1214 | .current_norm = V4L2_STD_NTSC_M, |
1226 | }; | 1215 | }; |
@@ -1276,7 +1265,7 @@ static int cx8802_blackbird_advise_release(struct cx8802_driver *drv) | |||
1276 | static void blackbird_unregister_video(struct cx8802_dev *dev) | 1265 | static void blackbird_unregister_video(struct cx8802_dev *dev) |
1277 | { | 1266 | { |
1278 | if (dev->mpeg_dev) { | 1267 | if (dev->mpeg_dev) { |
1279 | if (-1 != dev->mpeg_dev->minor) | 1268 | if (video_is_registered(dev->mpeg_dev)) |
1280 | video_unregister_device(dev->mpeg_dev); | 1269 | video_unregister_device(dev->mpeg_dev); |
1281 | else | 1270 | else |
1282 | video_device_release(dev->mpeg_dev); | 1271 | video_device_release(dev->mpeg_dev); |
@@ -1290,14 +1279,15 @@ static int blackbird_register_video(struct cx8802_dev *dev) | |||
1290 | 1279 | ||
1291 | dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci, | 1280 | dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci, |
1292 | &cx8802_mpeg_template,"mpeg"); | 1281 | &cx8802_mpeg_template,"mpeg"); |
1282 | video_set_drvdata(dev->mpeg_dev, dev); | ||
1293 | err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1); | 1283 | err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1); |
1294 | if (err < 0) { | 1284 | if (err < 0) { |
1295 | printk(KERN_INFO "%s/2: can't register mpeg device\n", | 1285 | printk(KERN_INFO "%s/2: can't register mpeg device\n", |
1296 | dev->core->name); | 1286 | dev->core->name); |
1297 | return err; | 1287 | return err; |
1298 | } | 1288 | } |
1299 | printk(KERN_INFO "%s/2: registered device video%d [mpeg]\n", | 1289 | printk(KERN_INFO "%s/2: registered device %s [mpeg]\n", |
1300 | dev->core->name, dev->mpeg_dev->num); | 1290 | dev->core->name, video_device_node_name(dev->mpeg_dev)); |
1301 | return 0; | 1291 | return 0; |
1302 | } | 1292 | } |
1303 | 1293 | ||
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 92b8cdf9fb8..f9fda18b410 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -360,7 +360,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
360 | snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); | 360 | snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); |
361 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); | 361 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); |
362 | 362 | ||
363 | err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); | 363 | err = ir_input_init(input_dev, &ir->ir, ir_type); |
364 | if (err < 0) | 364 | if (err < 0) |
365 | goto err_out_free; | 365 | goto err_out_free; |
366 | 366 | ||
@@ -383,7 +383,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
383 | cx88_ir_start(core, ir); | 383 | cx88_ir_start(core, ir); |
384 | 384 | ||
385 | /* all done */ | 385 | /* all done */ |
386 | err = input_register_device(ir->input); | 386 | err = ir_input_register(ir->input, ir_codes); |
387 | if (err) | 387 | if (err) |
388 | goto err_out_stop; | 388 | goto err_out_stop; |
389 | 389 | ||
@@ -393,8 +393,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
393 | cx88_ir_stop(core, ir); | 393 | cx88_ir_stop(core, ir); |
394 | core->ir = NULL; | 394 | core->ir = NULL; |
395 | err_out_free: | 395 | err_out_free: |
396 | ir_input_free(input_dev); | ||
397 | input_free_device(input_dev); | ||
398 | kfree(ir); | 396 | kfree(ir); |
399 | return err; | 397 | return err; |
400 | } | 398 | } |
@@ -408,8 +406,7 @@ int cx88_ir_fini(struct cx88_core *core) | |||
408 | return 0; | 406 | return 0; |
409 | 407 | ||
410 | cx88_ir_stop(core, ir); | 408 | cx88_ir_stop(core, ir); |
411 | ir_input_free(ir->input); | 409 | ir_input_unregister(ir->input); |
412 | input_unregister_device(ir->input); | ||
413 | kfree(ir); | 410 | kfree(ir); |
414 | 411 | ||
415 | /* done */ | 412 | /* done */ |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index de9ff0fc741..bb510489341 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -580,21 +580,6 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) | |||
580 | return 0; | 580 | return 0; |
581 | } | 581 | } |
582 | 582 | ||
583 | #if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \ | ||
584 | defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE) | ||
585 | struct cx8802_dev *cx8802_get_device(int minor) | ||
586 | { | ||
587 | struct cx8802_dev *dev; | ||
588 | |||
589 | list_for_each_entry(dev, &cx8802_devlist, devlist) | ||
590 | if (dev->mpeg_dev && dev->mpeg_dev->minor == minor) | ||
591 | return dev; | ||
592 | |||
593 | return NULL; | ||
594 | } | ||
595 | EXPORT_SYMBOL(cx8802_get_device); | ||
596 | #endif | ||
597 | |||
598 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype) | 583 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype) |
599 | { | 584 | { |
600 | struct cx8802_driver *d; | 585 | struct cx8802_driver *d; |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index d7e8fcee559..48c450f4a85 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -75,10 +75,6 @@ MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); | |||
75 | #define dprintk(level,fmt, arg...) if (video_debug >= level) \ | 75 | #define dprintk(level,fmt, arg...) if (video_debug >= level) \ |
76 | printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) | 76 | printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) |
77 | 77 | ||
78 | /* ------------------------------------------------------------------ */ | ||
79 | |||
80 | static LIST_HEAD(cx8800_devlist); | ||
81 | |||
82 | /* ------------------------------------------------------------------- */ | 78 | /* ------------------------------------------------------------------- */ |
83 | /* static data */ | 79 | /* static data */ |
84 | 80 | ||
@@ -753,38 +749,31 @@ static int get_ressource(struct cx8800_fh *fh) | |||
753 | 749 | ||
754 | static int video_open(struct file *file) | 750 | static int video_open(struct file *file) |
755 | { | 751 | { |
756 | int minor = video_devdata(file)->minor; | 752 | struct video_device *vdev = video_devdata(file); |
757 | struct cx8800_dev *h,*dev = NULL; | 753 | struct cx8800_dev *dev = video_drvdata(file); |
758 | struct cx88_core *core; | 754 | struct cx88_core *core; |
759 | struct cx8800_fh *fh; | 755 | struct cx8800_fh *fh; |
760 | enum v4l2_buf_type type = 0; | 756 | enum v4l2_buf_type type = 0; |
761 | int radio = 0; | 757 | int radio = 0; |
762 | 758 | ||
763 | lock_kernel(); | 759 | switch (vdev->vfl_type) { |
764 | list_for_each_entry(h, &cx8800_devlist, devlist) { | 760 | case VFL_TYPE_GRABBER: |
765 | if (h->video_dev->minor == minor) { | 761 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
766 | dev = h; | 762 | break; |
767 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 763 | case VFL_TYPE_VBI: |
768 | } | 764 | type = V4L2_BUF_TYPE_VBI_CAPTURE; |
769 | if (h->vbi_dev->minor == minor) { | 765 | break; |
770 | dev = h; | 766 | case VFL_TYPE_RADIO: |
771 | type = V4L2_BUF_TYPE_VBI_CAPTURE; | 767 | radio = 1; |
772 | } | 768 | break; |
773 | if (h->radio_dev && | ||
774 | h->radio_dev->minor == minor) { | ||
775 | radio = 1; | ||
776 | dev = h; | ||
777 | } | ||
778 | } | ||
779 | if (NULL == dev) { | ||
780 | unlock_kernel(); | ||
781 | return -ENODEV; | ||
782 | } | 769 | } |
783 | 770 | ||
771 | lock_kernel(); | ||
772 | |||
784 | core = dev->core; | 773 | core = dev->core; |
785 | 774 | ||
786 | dprintk(1,"open minor=%d radio=%d type=%s\n", | 775 | dprintk(1, "open dev=%s radio=%d type=%s\n", |
787 | minor,radio,v4l2_type_names[type]); | 776 | video_device_node_name(vdev), radio, v4l2_type_names[type]); |
788 | 777 | ||
789 | /* allocate + initialize per filehandle data */ | 778 | /* allocate + initialize per filehandle data */ |
790 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); | 779 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); |
@@ -1733,7 +1722,6 @@ static struct video_device cx8800_vbi_template; | |||
1733 | static struct video_device cx8800_video_template = { | 1722 | static struct video_device cx8800_video_template = { |
1734 | .name = "cx8800-video", | 1723 | .name = "cx8800-video", |
1735 | .fops = &video_fops, | 1724 | .fops = &video_fops, |
1736 | .minor = -1, | ||
1737 | .ioctl_ops = &video_ioctl_ops, | 1725 | .ioctl_ops = &video_ioctl_ops, |
1738 | .tvnorms = CX88_NORMS, | 1726 | .tvnorms = CX88_NORMS, |
1739 | .current_norm = V4L2_STD_NTSC_M, | 1727 | .current_norm = V4L2_STD_NTSC_M, |
@@ -1769,7 +1757,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { | |||
1769 | static struct video_device cx8800_radio_template = { | 1757 | static struct video_device cx8800_radio_template = { |
1770 | .name = "cx8800-radio", | 1758 | .name = "cx8800-radio", |
1771 | .fops = &radio_fops, | 1759 | .fops = &radio_fops, |
1772 | .minor = -1, | ||
1773 | .ioctl_ops = &radio_ioctl_ops, | 1760 | .ioctl_ops = &radio_ioctl_ops, |
1774 | }; | 1761 | }; |
1775 | 1762 | ||
@@ -1778,21 +1765,21 @@ static struct video_device cx8800_radio_template = { | |||
1778 | static void cx8800_unregister_video(struct cx8800_dev *dev) | 1765 | static void cx8800_unregister_video(struct cx8800_dev *dev) |
1779 | { | 1766 | { |
1780 | if (dev->radio_dev) { | 1767 | if (dev->radio_dev) { |
1781 | if (-1 != dev->radio_dev->minor) | 1768 | if (video_is_registered(dev->radio_dev)) |
1782 | video_unregister_device(dev->radio_dev); | 1769 | video_unregister_device(dev->radio_dev); |
1783 | else | 1770 | else |
1784 | video_device_release(dev->radio_dev); | 1771 | video_device_release(dev->radio_dev); |
1785 | dev->radio_dev = NULL; | 1772 | dev->radio_dev = NULL; |
1786 | } | 1773 | } |
1787 | if (dev->vbi_dev) { | 1774 | if (dev->vbi_dev) { |
1788 | if (-1 != dev->vbi_dev->minor) | 1775 | if (video_is_registered(dev->vbi_dev)) |
1789 | video_unregister_device(dev->vbi_dev); | 1776 | video_unregister_device(dev->vbi_dev); |
1790 | else | 1777 | else |
1791 | video_device_release(dev->vbi_dev); | 1778 | video_device_release(dev->vbi_dev); |
1792 | dev->vbi_dev = NULL; | 1779 | dev->vbi_dev = NULL; |
1793 | } | 1780 | } |
1794 | if (dev->video_dev) { | 1781 | if (dev->video_dev) { |
1795 | if (-1 != dev->video_dev->minor) | 1782 | if (video_is_registered(dev->video_dev)) |
1796 | video_unregister_device(dev->video_dev); | 1783 | video_unregister_device(dev->video_dev); |
1797 | else | 1784 | else |
1798 | video_device_release(dev->video_dev); | 1785 | video_device_release(dev->video_dev); |
@@ -1909,6 +1896,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1909 | /* register v4l devices */ | 1896 | /* register v4l devices */ |
1910 | dev->video_dev = cx88_vdev_init(core,dev->pci, | 1897 | dev->video_dev = cx88_vdev_init(core,dev->pci, |
1911 | &cx8800_video_template,"video"); | 1898 | &cx8800_video_template,"video"); |
1899 | video_set_drvdata(dev->video_dev, dev); | ||
1912 | err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, | 1900 | err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, |
1913 | video_nr[core->nr]); | 1901 | video_nr[core->nr]); |
1914 | if (err < 0) { | 1902 | if (err < 0) { |
@@ -1916,10 +1904,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1916 | core->name); | 1904 | core->name); |
1917 | goto fail_unreg; | 1905 | goto fail_unreg; |
1918 | } | 1906 | } |
1919 | printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n", | 1907 | printk(KERN_INFO "%s/0: registered device %s [v4l2]\n", |
1920 | core->name, dev->video_dev->num); | 1908 | core->name, video_device_node_name(dev->video_dev)); |
1921 | 1909 | ||
1922 | dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi"); | 1910 | dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi"); |
1911 | video_set_drvdata(dev->vbi_dev, dev); | ||
1923 | err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, | 1912 | err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, |
1924 | vbi_nr[core->nr]); | 1913 | vbi_nr[core->nr]); |
1925 | if (err < 0) { | 1914 | if (err < 0) { |
@@ -1927,12 +1916,13 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1927 | core->name); | 1916 | core->name); |
1928 | goto fail_unreg; | 1917 | goto fail_unreg; |
1929 | } | 1918 | } |
1930 | printk(KERN_INFO "%s/0: registered device vbi%d\n", | 1919 | printk(KERN_INFO "%s/0: registered device %s\n", |
1931 | core->name, dev->vbi_dev->num); | 1920 | core->name, video_device_node_name(dev->vbi_dev)); |
1932 | 1921 | ||
1933 | if (core->board.radio.type == CX88_RADIO) { | 1922 | if (core->board.radio.type == CX88_RADIO) { |
1934 | dev->radio_dev = cx88_vdev_init(core,dev->pci, | 1923 | dev->radio_dev = cx88_vdev_init(core,dev->pci, |
1935 | &cx8800_radio_template,"radio"); | 1924 | &cx8800_radio_template,"radio"); |
1925 | video_set_drvdata(dev->radio_dev, dev); | ||
1936 | err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, | 1926 | err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, |
1937 | radio_nr[core->nr]); | 1927 | radio_nr[core->nr]); |
1938 | if (err < 0) { | 1928 | if (err < 0) { |
@@ -1940,12 +1930,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1940 | core->name); | 1930 | core->name); |
1941 | goto fail_unreg; | 1931 | goto fail_unreg; |
1942 | } | 1932 | } |
1943 | printk(KERN_INFO "%s/0: registered device radio%d\n", | 1933 | printk(KERN_INFO "%s/0: registered device %s\n", |
1944 | core->name, dev->radio_dev->num); | 1934 | core->name, video_device_node_name(dev->radio_dev)); |
1945 | } | 1935 | } |
1946 | 1936 | ||
1947 | /* everything worked */ | 1937 | /* everything worked */ |
1948 | list_add_tail(&dev->devlist,&cx8800_devlist); | ||
1949 | pci_set_drvdata(pci_dev,dev); | 1938 | pci_set_drvdata(pci_dev,dev); |
1950 | 1939 | ||
1951 | /* initial device configuration */ | 1940 | /* initial device configuration */ |
@@ -2001,7 +1990,6 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev) | |||
2001 | 1990 | ||
2002 | /* free memory */ | 1991 | /* free memory */ |
2003 | btcx_riscmem_free(dev->pci,&dev->vidq.stopper); | 1992 | btcx_riscmem_free(dev->pci,&dev->vidq.stopper); |
2004 | list_del(&dev->devlist); | ||
2005 | cx88_core_put(core,dev->pci); | 1993 | cx88_core_put(core,dev->pci); |
2006 | kfree(dev); | 1994 | kfree(dev); |
2007 | } | 1995 | } |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index e1c52171010..b1499bf604e 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -423,7 +423,6 @@ struct cx8800_suspend_state { | |||
423 | 423 | ||
424 | struct cx8800_dev { | 424 | struct cx8800_dev { |
425 | struct cx88_core *core; | 425 | struct cx88_core *core; |
426 | struct list_head devlist; | ||
427 | spinlock_t slock; | 426 | spinlock_t slock; |
428 | 427 | ||
429 | /* various device info */ | 428 | /* various device info */ |
@@ -670,7 +669,6 @@ int cx88_audio_thread(void *data); | |||
670 | 669 | ||
671 | int cx8802_register_driver(struct cx8802_driver *drv); | 670 | int cx8802_register_driver(struct cx8802_driver *drv); |
672 | int cx8802_unregister_driver(struct cx8802_driver *drv); | 671 | int cx8802_unregister_driver(struct cx8802_driver *drv); |
673 | struct cx8802_dev *cx8802_get_device(int minor); | ||
674 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); | 672 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); |
675 | 673 | ||
676 | /* ----------------------------------------------------------- */ | 674 | /* ----------------------------------------------------------- */ |
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index c3916a42668..de22bc9faf2 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c | |||
@@ -70,7 +70,6 @@ | |||
70 | #include <linux/init.h> | 70 | #include <linux/init.h> |
71 | #include <linux/platform_device.h> | 71 | #include <linux/platform_device.h> |
72 | #include <linux/interrupt.h> | 72 | #include <linux/interrupt.h> |
73 | #include <linux/version.h> | ||
74 | #include <media/v4l2-common.h> | 73 | #include <media/v4l2-common.h> |
75 | #include <linux/io.h> | 74 | #include <linux/io.h> |
76 | #include <media/davinci/vpfe_capture.h> | 75 | #include <media/davinci/vpfe_capture.h> |
@@ -1967,7 +1966,6 @@ static __init int vpfe_probe(struct platform_device *pdev) | |||
1967 | vfd->release = video_device_release; | 1966 | vfd->release = video_device_release; |
1968 | vfd->fops = &vpfe_fops; | 1967 | vfd->fops = &vpfe_fops; |
1969 | vfd->ioctl_ops = &vpfe_ioctl_ops; | 1968 | vfd->ioctl_ops = &vpfe_ioctl_ops; |
1970 | vfd->minor = -1; | ||
1971 | vfd->tvnorms = 0; | 1969 | vfd->tvnorms = 0; |
1972 | vfd->current_norm = V4L2_STD_PAL; | 1970 | vfd->current_norm = V4L2_STD_PAL; |
1973 | vfd->v4l2_dev = &vpfe_dev->v4l2_dev; | 1971 | vfd->v4l2_dev = &vpfe_dev->v4l2_dev; |
@@ -2071,7 +2069,7 @@ probe_out_video_unregister: | |||
2071 | probe_out_v4l2_unregister: | 2069 | probe_out_v4l2_unregister: |
2072 | v4l2_device_unregister(&vpfe_dev->v4l2_dev); | 2070 | v4l2_device_unregister(&vpfe_dev->v4l2_dev); |
2073 | probe_out_video_release: | 2071 | probe_out_video_release: |
2074 | if (vpfe_dev->video_dev->minor == -1) | 2072 | if (!video_is_registered(vpfe_dev->video_dev)) |
2075 | video_device_release(vpfe_dev->video_dev); | 2073 | video_device_release(vpfe_dev->video_dev); |
2076 | probe_out_release_irq: | 2074 | probe_out_release_irq: |
2077 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); | 2075 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); |
@@ -2091,7 +2089,7 @@ probe_free_dev_mem: | |||
2091 | /* | 2089 | /* |
2092 | * vpfe_remove : It un-register device from V4L2 driver | 2090 | * vpfe_remove : It un-register device from V4L2 driver |
2093 | */ | 2091 | */ |
2094 | static int vpfe_remove(struct platform_device *pdev) | 2092 | static int __devexit vpfe_remove(struct platform_device *pdev) |
2095 | { | 2093 | { |
2096 | struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev); | 2094 | struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev); |
2097 | struct resource *res; | 2095 | struct resource *res; |
diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/video/davinci/vpif.c index 3b8eac31eca..1f532e31cd4 100644 --- a/drivers/media/video/davinci/vpif.c +++ b/drivers/media/video/davinci/vpif.c | |||
@@ -266,7 +266,7 @@ fail: | |||
266 | return status; | 266 | return status; |
267 | } | 267 | } |
268 | 268 | ||
269 | static int vpif_remove(struct platform_device *pdev) | 269 | static int __devexit vpif_remove(struct platform_device *pdev) |
270 | { | 270 | { |
271 | iounmap(vpif_base); | 271 | iounmap(vpif_base); |
272 | release_mem_region(res->start, res_len); | 272 | release_mem_region(res->start, res_len); |
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index d14cfb200ed..dfddef7228d 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c | |||
@@ -1347,7 +1347,6 @@ static const struct v4l2_file_operations vpif_fops = { | |||
1347 | static struct video_device vpif_video_template = { | 1347 | static struct video_device vpif_video_template = { |
1348 | .name = "vpif", | 1348 | .name = "vpif", |
1349 | .fops = &vpif_fops, | 1349 | .fops = &vpif_fops, |
1350 | .minor = -1, | ||
1351 | .ioctl_ops = &vpif_ioctl_ops, | 1350 | .ioctl_ops = &vpif_ioctl_ops, |
1352 | .tvnorms = DM646X_V4L2_STD, | 1351 | .tvnorms = DM646X_V4L2_STD, |
1353 | .current_norm = V4L2_STD_625_50, | 1352 | .current_norm = V4L2_STD_625_50, |
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c index 453236bd755..7ee72ecd3d8 100644 --- a/drivers/media/video/davinci/vpss.c +++ b/drivers/media/video/davinci/vpss.c | |||
@@ -268,7 +268,7 @@ fail1: | |||
268 | return status; | 268 | return status; |
269 | } | 269 | } |
270 | 270 | ||
271 | static int vpss_remove(struct platform_device *pdev) | 271 | static int __devexit vpss_remove(struct platform_device *pdev) |
272 | { | 272 | { |
273 | iounmap(oper_cfg.vpss_bl_regs_base); | 273 | iounmap(oper_cfg.vpss_bl_regs_base); |
274 | release_mem_region(oper_cfg.r1->start, oper_cfg.len1); | 274 | release_mem_region(oper_cfg.r1->start, oper_cfg.len1); |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 82da205047b..25100001fff 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -2285,7 +2285,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev) | |||
2285 | dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; | 2285 | dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; |
2286 | break; | 2286 | break; |
2287 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: | 2287 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: |
2288 | dev->init_data.ir_codes = &ir_codes_hauppauge_new_table; | 2288 | dev->init_data.ir_codes = &ir_codes_rc5_hauppauge_new_table; |
2289 | dev->init_data.get_key = em28xx_get_key_em_haup; | 2289 | dev->init_data.get_key = em28xx_get_key_em_haup; |
2290 | dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; | 2290 | dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; |
2291 | break; | 2291 | break; |
@@ -2653,7 +2653,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2653 | INIT_LIST_HEAD(&dev->vbiq.active); | 2653 | INIT_LIST_HEAD(&dev->vbiq.active); |
2654 | INIT_LIST_HEAD(&dev->vbiq.queued); | 2654 | INIT_LIST_HEAD(&dev->vbiq.queued); |
2655 | 2655 | ||
2656 | |||
2657 | if (dev->board.has_msp34xx) { | 2656 | if (dev->board.has_msp34xx) { |
2658 | /* Send a reset to other chips via gpio */ | 2657 | /* Send a reset to other chips via gpio */ |
2659 | errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); | 2658 | errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); |
@@ -2923,9 +2922,9 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
2923 | 2922 | ||
2924 | if (dev->users) { | 2923 | if (dev->users) { |
2925 | em28xx_warn | 2924 | em28xx_warn |
2926 | ("device /dev/video%d is open! Deregistration and memory " | 2925 | ("device %s is open! Deregistration and memory " |
2927 | "deallocation are deferred on close.\n", | 2926 | "deallocation are deferred on close.\n", |
2928 | dev->vdev->num); | 2927 | video_device_node_name(dev->vdev)); |
2929 | 2928 | ||
2930 | dev->state |= DEV_MISCONFIGURED; | 2929 | dev->state |= DEV_MISCONFIGURED; |
2931 | em28xx_uninit_isoc(dev); | 2930 | em28xx_uninit_isoc(dev); |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 3f86d36dff2..b311d4514bd 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -216,7 +216,7 @@ int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val) | |||
216 | * sets only some bits (specified by bitmask) of a register, by first reading | 216 | * sets only some bits (specified by bitmask) of a register, by first reading |
217 | * the actual value | 217 | * the actual value |
218 | */ | 218 | */ |
219 | static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | 219 | int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, |
220 | u8 bitmask) | 220 | u8 bitmask) |
221 | { | 221 | { |
222 | int oldval; | 222 | int oldval; |
@@ -1136,34 +1136,6 @@ void em28xx_wake_i2c(struct em28xx *dev) | |||
1136 | static LIST_HEAD(em28xx_devlist); | 1136 | static LIST_HEAD(em28xx_devlist); |
1137 | static DEFINE_MUTEX(em28xx_devlist_mutex); | 1137 | static DEFINE_MUTEX(em28xx_devlist_mutex); |
1138 | 1138 | ||
1139 | struct em28xx *em28xx_get_device(int minor, | ||
1140 | enum v4l2_buf_type *fh_type, | ||
1141 | int *has_radio) | ||
1142 | { | ||
1143 | struct em28xx *h, *dev = NULL; | ||
1144 | |||
1145 | *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1146 | *has_radio = 0; | ||
1147 | |||
1148 | mutex_lock(&em28xx_devlist_mutex); | ||
1149 | list_for_each_entry(h, &em28xx_devlist, devlist) { | ||
1150 | if (h->vdev->minor == minor) | ||
1151 | dev = h; | ||
1152 | if (h->vbi_dev && h->vbi_dev->minor == minor) { | ||
1153 | dev = h; | ||
1154 | *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1155 | } | ||
1156 | if (h->radio_dev && | ||
1157 | h->radio_dev->minor == minor) { | ||
1158 | dev = h; | ||
1159 | *has_radio = 1; | ||
1160 | } | ||
1161 | } | ||
1162 | mutex_unlock(&em28xx_devlist_mutex); | ||
1163 | |||
1164 | return dev; | ||
1165 | } | ||
1166 | |||
1167 | /* | 1139 | /* |
1168 | * em28xx_realease_resources() | 1140 | * em28xx_realease_resources() |
1169 | * unregisters the v4l2,i2c and usb devices | 1141 | * unregisters the v4l2,i2c and usb devices |
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index d96ec7c09dc..af0d935c29b 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -112,10 +112,13 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
112 | int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 112 | int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
113 | { | 113 | { |
114 | unsigned char buf[2]; | 114 | unsigned char buf[2]; |
115 | unsigned char code; | 115 | u16 code; |
116 | int size; | ||
116 | 117 | ||
117 | /* poll IR chip */ | 118 | /* poll IR chip */ |
118 | if (2 != i2c_master_recv(ir->c, buf, 2)) | 119 | size = i2c_master_recv(ir->c, buf, sizeof(buf)); |
120 | |||
121 | if (size != 2) | ||
119 | return -EIO; | 122 | return -EIO; |
120 | 123 | ||
121 | /* Does eliminate repeated parity code */ | 124 | /* Does eliminate repeated parity code */ |
@@ -124,16 +127,30 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
124 | 127 | ||
125 | ir->old = buf[1]; | 128 | ir->old = buf[1]; |
126 | 129 | ||
127 | /* Rearranges bits to the right order */ | 130 | /* |
128 | code = ((buf[0]&0x01)<<5) | /* 0010 0000 */ | 131 | * Rearranges bits to the right order. |
129 | ((buf[0]&0x02)<<3) | /* 0001 0000 */ | 132 | * The bit order were determined experimentally by using |
130 | ((buf[0]&0x04)<<1) | /* 0000 1000 */ | 133 | * The original Hauppauge Grey IR and another RC5 that uses addr=0x08 |
131 | ((buf[0]&0x08)>>1) | /* 0000 0100 */ | 134 | * The RC5 code has 14 bits, but we've experimentally determined |
132 | ((buf[0]&0x10)>>3) | /* 0000 0010 */ | 135 | * the meaning for only 11 bits. |
133 | ((buf[0]&0x20)>>5); /* 0000 0001 */ | 136 | * So, the code translation is not complete. Yet, it is enough to |
134 | 137 | * work with the provided RC5 IR. | |
135 | i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n", | 138 | */ |
136 | code, buf[0]); | 139 | code = |
140 | ((buf[0] & 0x01) ? 0x0020 : 0) | /* 0010 0000 */ | ||
141 | ((buf[0] & 0x02) ? 0x0010 : 0) | /* 0001 0000 */ | ||
142 | ((buf[0] & 0x04) ? 0x0008 : 0) | /* 0000 1000 */ | ||
143 | ((buf[0] & 0x08) ? 0x0004 : 0) | /* 0000 0100 */ | ||
144 | ((buf[0] & 0x10) ? 0x0002 : 0) | /* 0000 0010 */ | ||
145 | ((buf[0] & 0x20) ? 0x0001 : 0) | /* 0000 0001 */ | ||
146 | ((buf[1] & 0x08) ? 0x1000 : 0) | /* 0001 0000 */ | ||
147 | ((buf[1] & 0x10) ? 0x0800 : 0) | /* 0000 1000 */ | ||
148 | ((buf[1] & 0x20) ? 0x0400 : 0) | /* 0000 0100 */ | ||
149 | ((buf[1] & 0x40) ? 0x0200 : 0) | /* 0000 0010 */ | ||
150 | ((buf[1] & 0x80) ? 0x0100 : 0); /* 0000 0001 */ | ||
151 | |||
152 | i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x%02x)\n", | ||
153 | code, buf[1], buf[0]); | ||
137 | 154 | ||
138 | /* return key */ | 155 | /* return key */ |
139 | *ir_key = code; | 156 | *ir_key = code; |
@@ -337,19 +354,28 @@ int em28xx_ir_init(struct em28xx *dev) | |||
337 | goto err_out_free; | 354 | goto err_out_free; |
338 | 355 | ||
339 | ir->input = input_dev; | 356 | ir->input = input_dev; |
357 | ir_config = EM2874_IR_RC5; | ||
358 | |||
359 | /* Adjust xclk based o IR table for RC5/NEC tables */ | ||
360 | if (dev->board.ir_codes->ir_type == IR_TYPE_RC5) { | ||
361 | dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; | ||
362 | ir->full_code = 1; | ||
363 | } else if (dev->board.ir_codes->ir_type == IR_TYPE_NEC) { | ||
364 | dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; | ||
365 | ir_config = EM2874_IR_NEC; | ||
366 | ir->full_code = 1; | ||
367 | } | ||
368 | em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, | ||
369 | EM28XX_XCLK_IR_RC5_MODE); | ||
340 | 370 | ||
341 | /* Setup the proper handler based on the chip */ | 371 | /* Setup the proper handler based on the chip */ |
342 | switch (dev->chip_id) { | 372 | switch (dev->chip_id) { |
343 | case CHIP_ID_EM2860: | 373 | case CHIP_ID_EM2860: |
344 | case CHIP_ID_EM2883: | 374 | case CHIP_ID_EM2883: |
345 | if (dev->model == EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950) | ||
346 | ir->full_code = 1; | ||
347 | ir->get_key = default_polling_getkey; | 375 | ir->get_key = default_polling_getkey; |
348 | break; | 376 | break; |
349 | case CHIP_ID_EM2874: | 377 | case CHIP_ID_EM2874: |
350 | ir->get_key = em2874_polling_getkey; | 378 | ir->get_key = em2874_polling_getkey; |
351 | /* For now we only support RC5, so enable it */ | ||
352 | ir_config = EM2874_IR_RC5; | ||
353 | em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); | 379 | em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); |
354 | break; | 380 | break; |
355 | default: | 381 | default: |
@@ -367,8 +393,7 @@ int em28xx_ir_init(struct em28xx *dev) | |||
367 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); | 393 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); |
368 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); | 394 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); |
369 | 395 | ||
370 | err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, | 396 | err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER); |
371 | dev->board.ir_codes); | ||
372 | if (err < 0) | 397 | if (err < 0) |
373 | goto err_out_free; | 398 | goto err_out_free; |
374 | 399 | ||
@@ -387,7 +412,7 @@ int em28xx_ir_init(struct em28xx *dev) | |||
387 | em28xx_ir_start(ir); | 412 | em28xx_ir_start(ir); |
388 | 413 | ||
389 | /* all done */ | 414 | /* all done */ |
390 | err = input_register_device(ir->input); | 415 | err = ir_input_register(ir->input, dev->board.ir_codes); |
391 | if (err) | 416 | if (err) |
392 | goto err_out_stop; | 417 | goto err_out_stop; |
393 | 418 | ||
@@ -396,8 +421,6 @@ int em28xx_ir_init(struct em28xx *dev) | |||
396 | em28xx_ir_stop(ir); | 421 | em28xx_ir_stop(ir); |
397 | dev->ir = NULL; | 422 | dev->ir = NULL; |
398 | err_out_free: | 423 | err_out_free: |
399 | ir_input_free(input_dev); | ||
400 | input_free_device(input_dev); | ||
401 | kfree(ir); | 424 | kfree(ir); |
402 | return err; | 425 | return err; |
403 | } | 426 | } |
@@ -411,8 +434,7 @@ int em28xx_ir_fini(struct em28xx *dev) | |||
411 | return 0; | 434 | return 0; |
412 | 435 | ||
413 | em28xx_ir_stop(ir); | 436 | em28xx_ir_stop(ir); |
414 | ir_input_free(ir->input); | 437 | ir_input_unregister(ir->input); |
415 | input_unregister_device(ir->input); | ||
416 | kfree(ir); | 438 | kfree(ir); |
417 | 439 | ||
418 | /* done */ | 440 | /* done */ |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 7ad65370f27..849b18c9403 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -2081,22 +2081,30 @@ static int radio_queryctrl(struct file *file, void *priv, | |||
2081 | */ | 2081 | */ |
2082 | static int em28xx_v4l2_open(struct file *filp) | 2082 | static int em28xx_v4l2_open(struct file *filp) |
2083 | { | 2083 | { |
2084 | int minor = video_devdata(filp)->minor; | 2084 | int errCode = 0, radio = 0; |
2085 | int errCode = 0, radio; | 2085 | struct video_device *vdev = video_devdata(filp); |
2086 | struct em28xx *dev; | 2086 | struct em28xx *dev = video_drvdata(filp); |
2087 | enum v4l2_buf_type fh_type; | 2087 | enum v4l2_buf_type fh_type = 0; |
2088 | struct em28xx_fh *fh; | 2088 | struct em28xx_fh *fh; |
2089 | enum v4l2_field field; | 2089 | enum v4l2_field field; |
2090 | 2090 | ||
2091 | dev = em28xx_get_device(minor, &fh_type, &radio); | 2091 | switch (vdev->vfl_type) { |
2092 | 2092 | case VFL_TYPE_GRABBER: | |
2093 | if (NULL == dev) | 2093 | fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
2094 | return -ENODEV; | 2094 | break; |
2095 | case VFL_TYPE_VBI: | ||
2096 | fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
2097 | break; | ||
2098 | case VFL_TYPE_RADIO: | ||
2099 | radio = 1; | ||
2100 | break; | ||
2101 | } | ||
2095 | 2102 | ||
2096 | mutex_lock(&dev->lock); | 2103 | mutex_lock(&dev->lock); |
2097 | 2104 | ||
2098 | em28xx_videodbg("open minor=%d type=%s users=%d\n", | 2105 | em28xx_videodbg("open dev=%s type=%s users=%d\n", |
2099 | minor, v4l2_type_names[fh_type], dev->users); | 2106 | video_device_node_name(vdev), v4l2_type_names[fh_type], |
2107 | dev->users); | ||
2100 | 2108 | ||
2101 | 2109 | ||
2102 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | 2110 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); |
@@ -2160,25 +2168,25 @@ void em28xx_release_analog_resources(struct em28xx *dev) | |||
2160 | /*FIXME: I2C IR should be disconnected */ | 2168 | /*FIXME: I2C IR should be disconnected */ |
2161 | 2169 | ||
2162 | if (dev->radio_dev) { | 2170 | if (dev->radio_dev) { |
2163 | if (-1 != dev->radio_dev->minor) | 2171 | if (video_is_registered(dev->radio_dev)) |
2164 | video_unregister_device(dev->radio_dev); | 2172 | video_unregister_device(dev->radio_dev); |
2165 | else | 2173 | else |
2166 | video_device_release(dev->radio_dev); | 2174 | video_device_release(dev->radio_dev); |
2167 | dev->radio_dev = NULL; | 2175 | dev->radio_dev = NULL; |
2168 | } | 2176 | } |
2169 | if (dev->vbi_dev) { | 2177 | if (dev->vbi_dev) { |
2170 | em28xx_info("V4L2 device /dev/vbi%d deregistered\n", | 2178 | em28xx_info("V4L2 device %s deregistered\n", |
2171 | dev->vbi_dev->num); | 2179 | video_device_node_name(dev->vbi_dev)); |
2172 | if (-1 != dev->vbi_dev->minor) | 2180 | if (video_is_registered(dev->vbi_dev)) |
2173 | video_unregister_device(dev->vbi_dev); | 2181 | video_unregister_device(dev->vbi_dev); |
2174 | else | 2182 | else |
2175 | video_device_release(dev->vbi_dev); | 2183 | video_device_release(dev->vbi_dev); |
2176 | dev->vbi_dev = NULL; | 2184 | dev->vbi_dev = NULL; |
2177 | } | 2185 | } |
2178 | if (dev->vdev) { | 2186 | if (dev->vdev) { |
2179 | em28xx_info("V4L2 device /dev/video%d deregistered\n", | 2187 | em28xx_info("V4L2 device %s deregistered\n", |
2180 | dev->vdev->num); | 2188 | video_device_node_name(dev->vdev)); |
2181 | if (-1 != dev->vdev->minor) | 2189 | if (video_is_registered(dev->vdev)) |
2182 | video_unregister_device(dev->vdev); | 2190 | video_unregister_device(dev->vdev); |
2183 | else | 2191 | else |
2184 | video_device_release(dev->vdev); | 2192 | video_device_release(dev->vdev); |
@@ -2397,8 +2405,6 @@ static const struct video_device em28xx_video_template = { | |||
2397 | .release = video_device_release, | 2405 | .release = video_device_release, |
2398 | .ioctl_ops = &video_ioctl_ops, | 2406 | .ioctl_ops = &video_ioctl_ops, |
2399 | 2407 | ||
2400 | .minor = -1, | ||
2401 | |||
2402 | .tvnorms = V4L2_STD_ALL, | 2408 | .tvnorms = V4L2_STD_ALL, |
2403 | .current_norm = V4L2_STD_PAL, | 2409 | .current_norm = V4L2_STD_PAL, |
2404 | }; | 2410 | }; |
@@ -2433,7 +2439,6 @@ static struct video_device em28xx_radio_template = { | |||
2433 | .name = "em28xx-radio", | 2439 | .name = "em28xx-radio", |
2434 | .fops = &radio_fops, | 2440 | .fops = &radio_fops, |
2435 | .ioctl_ops = &radio_ioctl_ops, | 2441 | .ioctl_ops = &radio_ioctl_ops, |
2436 | .minor = -1, | ||
2437 | }; | 2442 | }; |
2438 | 2443 | ||
2439 | /******************************** usb interface ******************************/ | 2444 | /******************************** usb interface ******************************/ |
@@ -2451,7 +2456,6 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
2451 | return NULL; | 2456 | return NULL; |
2452 | 2457 | ||
2453 | *vfd = *template; | 2458 | *vfd = *template; |
2454 | vfd->minor = -1; | ||
2455 | vfd->v4l2_dev = &dev->v4l2_dev; | 2459 | vfd->v4l2_dev = &dev->v4l2_dev; |
2456 | vfd->release = video_device_release; | 2460 | vfd->release = video_device_release; |
2457 | vfd->debug = video_debug; | 2461 | vfd->debug = video_debug; |
@@ -2459,6 +2463,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
2459 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", | 2463 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", |
2460 | dev->name, type_name); | 2464 | dev->name, type_name); |
2461 | 2465 | ||
2466 | video_set_drvdata(vfd, dev); | ||
2462 | return vfd; | 2467 | return vfd; |
2463 | } | 2468 | } |
2464 | 2469 | ||
@@ -2540,16 +2545,16 @@ int em28xx_register_analog_devices(struct em28xx *dev) | |||
2540 | em28xx_errdev("can't register radio device\n"); | 2545 | em28xx_errdev("can't register radio device\n"); |
2541 | return ret; | 2546 | return ret; |
2542 | } | 2547 | } |
2543 | em28xx_info("Registered radio device as /dev/radio%d\n", | 2548 | em28xx_info("Registered radio device as %s\n", |
2544 | dev->radio_dev->num); | 2549 | video_device_node_name(dev->radio_dev)); |
2545 | } | 2550 | } |
2546 | 2551 | ||
2547 | em28xx_info("V4L2 video device registered as /dev/video%d\n", | 2552 | em28xx_info("V4L2 video device registered as %s\n", |
2548 | dev->vdev->num); | 2553 | video_device_node_name(dev->vdev)); |
2549 | 2554 | ||
2550 | if (dev->vbi_dev) | 2555 | if (dev->vbi_dev) |
2551 | em28xx_info("V4L2 VBI device registered as /dev/vbi%d\n", | 2556 | em28xx_info("V4L2 VBI device registered as %s\n", |
2552 | dev->vbi_dev->num); | 2557 | video_device_node_name(dev->vbi_dev)); |
2553 | 2558 | ||
2554 | return 0; | 2559 | return 0; |
2555 | } | 2560 | } |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 441df644ddb..80d9b4fa1b9 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -643,6 +643,8 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
643 | int len); | 643 | int len); |
644 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); | 644 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); |
645 | int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val); | 645 | int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val); |
646 | int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | ||
647 | u8 bitmask); | ||
646 | 648 | ||
647 | int em28xx_read_ac97(struct em28xx *dev, u8 reg); | 649 | int em28xx_read_ac97(struct em28xx *dev, u8 reg); |
648 | int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val); | 650 | int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val); |
@@ -666,9 +668,6 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | |||
666 | void em28xx_wake_i2c(struct em28xx *dev); | 668 | void em28xx_wake_i2c(struct em28xx *dev); |
667 | void em28xx_remove_from_devlist(struct em28xx *dev); | 669 | void em28xx_remove_from_devlist(struct em28xx *dev); |
668 | void em28xx_add_into_devlist(struct em28xx *dev); | 670 | void em28xx_add_into_devlist(struct em28xx *dev); |
669 | struct em28xx *em28xx_get_device(int minor, | ||
670 | enum v4l2_buf_type *fh_type, | ||
671 | int *has_radio); | ||
672 | int em28xx_register_extension(struct em28xx_ops *dev); | 671 | int em28xx_register_extension(struct em28xx_ops *dev); |
673 | void em28xx_unregister_extension(struct em28xx_ops *dev); | 672 | void em28xx_unregister_extension(struct em28xx_ops *dev); |
674 | void em28xx_init_extension(struct em28xx *dev); | 673 | void em28xx_init_extension(struct em28xx *dev); |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 88987a57cf7..e6c23d50986 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
@@ -587,8 +587,8 @@ static int et61x251_stream_interrupt(struct et61x251_device* cam) | |||
587 | else if (cam->stream != STREAM_OFF) { | 587 | else if (cam->stream != STREAM_OFF) { |
588 | cam->state |= DEV_MISCONFIGURED; | 588 | cam->state |= DEV_MISCONFIGURED; |
589 | DBG(1, "URB timeout reached. The camera is misconfigured. To " | 589 | DBG(1, "URB timeout reached. The camera is misconfigured. To " |
590 | "use it, close and open /dev/video%d again.", | 590 | "use it, close and open %s again.", |
591 | cam->v4ldev->num); | 591 | video_device_node_name(cam->v4ldev)); |
592 | return -EIO; | 592 | return -EIO; |
593 | } | 593 | } |
594 | 594 | ||
@@ -1195,7 +1195,8 @@ static void et61x251_release_resources(struct kref *kref) | |||
1195 | 1195 | ||
1196 | cam = container_of(kref, struct et61x251_device, kref); | 1196 | cam = container_of(kref, struct et61x251_device, kref); |
1197 | 1197 | ||
1198 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num); | 1198 | DBG(2, "V4L2 device %s deregistered", |
1199 | video_device_node_name(cam->v4ldev)); | ||
1199 | video_set_drvdata(cam->v4ldev, NULL); | 1200 | video_set_drvdata(cam->v4ldev, NULL); |
1200 | video_unregister_device(cam->v4ldev); | 1201 | video_unregister_device(cam->v4ldev); |
1201 | usb_put_dev(cam->usbdev); | 1202 | usb_put_dev(cam->usbdev); |
@@ -1236,8 +1237,8 @@ static int et61x251_open(struct file *filp) | |||
1236 | } | 1237 | } |
1237 | 1238 | ||
1238 | if (cam->users) { | 1239 | if (cam->users) { |
1239 | DBG(2, "Device /dev/video%d is already in use", | 1240 | DBG(2, "Device %s is already in use", |
1240 | cam->v4ldev->num); | 1241 | video_device_node_name(cam->v4ldev)); |
1241 | DBG(3, "Simultaneous opens are not supported"); | 1242 | DBG(3, "Simultaneous opens are not supported"); |
1242 | if ((filp->f_flags & O_NONBLOCK) || | 1243 | if ((filp->f_flags & O_NONBLOCK) || |
1243 | (filp->f_flags & O_NDELAY)) { | 1244 | (filp->f_flags & O_NDELAY)) { |
@@ -1280,7 +1281,8 @@ static int et61x251_open(struct file *filp) | |||
1280 | cam->frame_count = 0; | 1281 | cam->frame_count = 0; |
1281 | et61x251_empty_framequeues(cam); | 1282 | et61x251_empty_framequeues(cam); |
1282 | 1283 | ||
1283 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num); | 1284 | DBG(3, "Video device %s is open", |
1285 | video_device_node_name(cam->v4ldev)); | ||
1284 | 1286 | ||
1285 | out: | 1287 | out: |
1286 | mutex_unlock(&cam->open_mutex); | 1288 | mutex_unlock(&cam->open_mutex); |
@@ -1304,7 +1306,8 @@ static int et61x251_release(struct file *filp) | |||
1304 | cam->users--; | 1306 | cam->users--; |
1305 | wake_up_interruptible_nr(&cam->wait_open, 1); | 1307 | wake_up_interruptible_nr(&cam->wait_open, 1); |
1306 | 1308 | ||
1307 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num); | 1309 | DBG(3, "Video device %s closed", |
1310 | video_device_node_name(cam->v4ldev)); | ||
1308 | 1311 | ||
1309 | kref_put(&cam->kref, et61x251_release_resources); | 1312 | kref_put(&cam->kref, et61x251_release_resources); |
1310 | 1313 | ||
@@ -1846,8 +1849,8 @@ et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) | |||
1846 | if (err) { /* atomic, no rollback in ioctl() */ | 1849 | if (err) { /* atomic, no rollback in ioctl() */ |
1847 | cam->state |= DEV_MISCONFIGURED; | 1850 | cam->state |= DEV_MISCONFIGURED; |
1848 | DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " | 1851 | DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " |
1849 | "use the camera, close and open /dev/video%d again.", | 1852 | "use the camera, close and open %s again.", |
1850 | cam->v4ldev->num); | 1853 | video_device_node_name(cam->v4ldev)); |
1851 | return -EIO; | 1854 | return -EIO; |
1852 | } | 1855 | } |
1853 | 1856 | ||
@@ -1859,8 +1862,8 @@ et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) | |||
1859 | nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { | 1862 | nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { |
1860 | cam->state |= DEV_MISCONFIGURED; | 1863 | cam->state |= DEV_MISCONFIGURED; |
1861 | DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " | 1864 | DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " |
1862 | "use the camera, close and open /dev/video%d again.", | 1865 | "use the camera, close and open %s again.", |
1863 | cam->v4ldev->num); | 1866 | video_device_node_name(cam->v4ldev)); |
1864 | return -ENOMEM; | 1867 | return -ENOMEM; |
1865 | } | 1868 | } |
1866 | 1869 | ||
@@ -2069,8 +2072,8 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, | |||
2069 | if (err) { /* atomic, no rollback in ioctl() */ | 2072 | if (err) { /* atomic, no rollback in ioctl() */ |
2070 | cam->state |= DEV_MISCONFIGURED; | 2073 | cam->state |= DEV_MISCONFIGURED; |
2071 | DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " | 2074 | DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " |
2072 | "use the camera, close and open /dev/video%d again.", | 2075 | "use the camera, close and open %s again.", |
2073 | cam->v4ldev->num); | 2076 | video_device_node_name(cam->v4ldev)); |
2074 | return -EIO; | 2077 | return -EIO; |
2075 | } | 2078 | } |
2076 | 2079 | ||
@@ -2081,8 +2084,8 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, | |||
2081 | nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { | 2084 | nbuffers != et61x251_request_buffers(cam, nbuffers, cam->io)) { |
2082 | cam->state |= DEV_MISCONFIGURED; | 2085 | cam->state |= DEV_MISCONFIGURED; |
2083 | DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " | 2086 | DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " |
2084 | "use the camera, close and open /dev/video%d again.", | 2087 | "use the camera, close and open %s again.", |
2085 | cam->v4ldev->num); | 2088 | video_device_node_name(cam->v4ldev)); |
2086 | return -ENOMEM; | 2089 | return -ENOMEM; |
2087 | } | 2090 | } |
2088 | 2091 | ||
@@ -2130,7 +2133,7 @@ et61x251_vidioc_s_jpegcomp(struct et61x251_device* cam, void __user * arg) | |||
2130 | cam->state |= DEV_MISCONFIGURED; | 2133 | cam->state |= DEV_MISCONFIGURED; |
2131 | DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " | 2134 | DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " |
2132 | "problems. To use the camera, close and open " | 2135 | "problems. To use the camera, close and open " |
2133 | "/dev/video%d again.", cam->v4ldev->num); | 2136 | "%s again.", video_device_node_name(cam->v4ldev)); |
2134 | return -EIO; | 2137 | return -EIO; |
2135 | } | 2138 | } |
2136 | 2139 | ||
@@ -2584,7 +2587,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2584 | 2587 | ||
2585 | strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera"); | 2588 | strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera"); |
2586 | cam->v4ldev->fops = &et61x251_fops; | 2589 | cam->v4ldev->fops = &et61x251_fops; |
2587 | cam->v4ldev->minor = video_nr[dev_nr]; | ||
2588 | cam->v4ldev->release = video_device_release; | 2590 | cam->v4ldev->release = video_device_release; |
2589 | cam->v4ldev->parent = &udev->dev; | 2591 | cam->v4ldev->parent = &udev->dev; |
2590 | video_set_drvdata(cam->v4ldev, cam); | 2592 | video_set_drvdata(cam->v4ldev, cam); |
@@ -2603,7 +2605,8 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2603 | goto fail; | 2605 | goto fail; |
2604 | } | 2606 | } |
2605 | 2607 | ||
2606 | DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num); | 2608 | DBG(2, "V4L2 device registered as %s", |
2609 | video_device_node_name(cam->v4ldev)); | ||
2607 | 2610 | ||
2608 | cam->module_param.force_munmap = force_munmap[dev_nr]; | 2611 | cam->module_param.force_munmap = force_munmap[dev_nr]; |
2609 | cam->module_param.frame_timeout = frame_timeout[dev_nr]; | 2612 | cam->module_param.frame_timeout = frame_timeout[dev_nr]; |
@@ -2654,9 +2657,9 @@ static void et61x251_usb_disconnect(struct usb_interface* intf) | |||
2654 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); | 2657 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); |
2655 | 2658 | ||
2656 | if (cam->users) { | 2659 | if (cam->users) { |
2657 | DBG(2, "Device /dev/video%d is open! Deregistration and " | 2660 | DBG(2, "Device %s is open! Deregistration and memory " |
2658 | "memory deallocation are deferred.", | 2661 | "deallocation are deferred.", |
2659 | cam->v4ldev->num); | 2662 | video_device_node_name(cam->v4ldev)); |
2660 | cam->state |= DEV_MISCONFIGURED; | 2663 | cam->state |= DEV_MISCONFIGURED; |
2661 | et61x251_stop_transfer(cam); | 2664 | et61x251_stop_transfer(cam); |
2662 | cam->state |= DEV_DISCONNECTED; | 2665 | cam->state |= DEV_DISCONNECTED; |
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 2f0b8d621e0..c98b5d69c43 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c | |||
@@ -1046,14 +1046,14 @@ static struct sd_desc sd_desc = { | |||
1046 | }; | 1046 | }; |
1047 | 1047 | ||
1048 | /* -- module initialisation -- */ | 1048 | /* -- module initialisation -- */ |
1049 | static __devinitdata struct usb_device_id device_table[] = { | 1049 | static const struct usb_device_id device_table[] __devinitconst = { |
1050 | {USB_DEVICE(0x0572, 0x0041)}, | 1050 | {USB_DEVICE(0x0572, 0x0041)}, |
1051 | {} | 1051 | {} |
1052 | }; | 1052 | }; |
1053 | MODULE_DEVICE_TABLE(usb, device_table); | 1053 | MODULE_DEVICE_TABLE(usb, device_table); |
1054 | 1054 | ||
1055 | /* -- device connect -- */ | 1055 | /* -- device connect -- */ |
1056 | static int sd_probe(struct usb_interface *intf, | 1056 | static int __devinit sd_probe(struct usb_interface *intf, |
1057 | const struct usb_device_id *id) | 1057 | const struct usb_device_id *id) |
1058 | { | 1058 | { |
1059 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | 1059 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), |
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 9de86419ae1..fdf4c0ec5e7 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c | |||
@@ -864,7 +864,7 @@ static struct sd_desc sd_desc = { | |||
864 | }; | 864 | }; |
865 | 865 | ||
866 | /* -- module initialisation -- */ | 866 | /* -- module initialisation -- */ |
867 | static __devinitdata struct usb_device_id device_table[] = { | 867 | static const struct usb_device_id device_table[] __devinitconst = { |
868 | {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, | 868 | {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, |
869 | #if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE | 869 | #if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE |
870 | {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, | 870 | {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, |
@@ -875,7 +875,7 @@ static __devinitdata struct usb_device_id device_table[] = { | |||
875 | MODULE_DEVICE_TABLE(usb, device_table); | 875 | MODULE_DEVICE_TABLE(usb, device_table); |
876 | 876 | ||
877 | /* -- device connect -- */ | 877 | /* -- device connect -- */ |
878 | static int sd_probe(struct usb_interface *intf, | 878 | static int __devinit sd_probe(struct usb_interface *intf, |
879 | const struct usb_device_id *id) | 879 | const struct usb_device_id *id) |
880 | { | 880 | { |
881 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | 881 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), |
diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c index 1355e526ee8..c276a7debde 100644 --- a/drivers/media/video/gspca/gl860/gl860-mi1320.c +++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c | |||
@@ -345,7 +345,7 @@ static int mi1320_configure_alt(struct gspca_dev *gspca_dev) | |||
345 | return 0; | 345 | return 0; |
346 | } | 346 | } |
347 | 347 | ||
348 | int mi1320_camera_settings(struct gspca_dev *gspca_dev) | 348 | static int mi1320_camera_settings(struct gspca_dev *gspca_dev) |
349 | { | 349 | { |
350 | struct sd *sd = (struct sd *) gspca_dev; | 350 | struct sd *sd = (struct sd *) gspca_dev; |
351 | 351 | ||
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c index 80cb3f1b36f..7c31b4f2abe 100644 --- a/drivers/media/video/gspca/gl860/gl860-mi2020.c +++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c | |||
@@ -769,7 +769,7 @@ static int mi2020_configure_alt(struct gspca_dev *gspca_dev) | |||
769 | return 0; | 769 | return 0; |
770 | } | 770 | } |
771 | 771 | ||
772 | int mi2020_camera_settings(struct gspca_dev *gspca_dev) | 772 | static int mi2020_camera_settings(struct gspca_dev *gspca_dev) |
773 | { | 773 | { |
774 | struct sd *sd = (struct sd *) gspca_dev; | 774 | struct sd *sd = (struct sd *) gspca_dev; |
775 | 775 | ||
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index a695e0ae13c..4878c8f6654 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c | |||
@@ -40,7 +40,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
40 | static void sd_callback(struct gspca_dev *gspca_dev); | 40 | static void sd_callback(struct gspca_dev *gspca_dev); |
41 | 41 | ||
42 | static int gl860_guess_sensor(struct gspca_dev *gspca_dev, | 42 | static int gl860_guess_sensor(struct gspca_dev *gspca_dev, |
43 | s32 vendor_id, s32 product_id); | 43 | u16 vendor_id, u16 product_id); |
44 | 44 | ||
45 | /*============================ driver options ==============================*/ | 45 | /*============================ driver options ==============================*/ |
46 | 46 | ||
@@ -326,11 +326,11 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
326 | { | 326 | { |
327 | struct sd *sd = (struct sd *) gspca_dev; | 327 | struct sd *sd = (struct sd *) gspca_dev; |
328 | struct cam *cam; | 328 | struct cam *cam; |
329 | s32 vendor_id, product_id; | 329 | u16 vendor_id, product_id; |
330 | 330 | ||
331 | /* Get USB VendorID and ProductID */ | 331 | /* Get USB VendorID and ProductID */ |
332 | vendor_id = le16_to_cpu(id->idVendor); | 332 | vendor_id = id->idVendor; |
333 | product_id = le16_to_cpu(id->idProduct); | 333 | product_id = id->idProduct; |
334 | 334 | ||
335 | sd->nbRightUp = 1; | 335 | sd->nbRightUp = 1; |
336 | sd->nbIm = -1; | 336 | sd->nbIm = -1; |
@@ -534,8 +534,8 @@ static int sd_probe(struct usb_interface *intf, | |||
534 | gspca_dev = usb_get_intfdata(intf); | 534 | gspca_dev = usb_get_intfdata(intf); |
535 | 535 | ||
536 | PDEBUG(D_PROBE, | 536 | PDEBUG(D_PROBE, |
537 | "Camera is now controlling video device /dev/video%d", | 537 | "Camera is now controlling video device %s", |
538 | gspca_dev->vdev.minor); | 538 | video_device_node_name(&gspca_dev->vdev)); |
539 | } | 539 | } |
540 | 540 | ||
541 | return ret; | 541 | return ret; |
@@ -673,7 +673,7 @@ void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len) | |||
673 | } | 673 | } |
674 | 674 | ||
675 | static int gl860_guess_sensor(struct gspca_dev *gspca_dev, | 675 | static int gl860_guess_sensor(struct gspca_dev *gspca_dev, |
676 | s32 vendor_id, s32 product_id) | 676 | u16 vendor_id, u16 product_id) |
677 | { | 677 | { |
678 | struct sd *sd = (struct sd *) gspca_dev; | 678 | struct sd *sd = (struct sd *) gspca_dev; |
679 | u8 probe, nb26, nb96, nOV, ntry; | 679 | u8 probe, nb26, nb96, nOV, ntry; |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 4076f8e5a6f..e930a67d526 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -304,7 +304,6 @@ void gspca_frame_add(struct gspca_dev *gspca_dev, | |||
304 | j = gspca_dev->fr_queue[i]; | 304 | j = gspca_dev->fr_queue[i]; |
305 | gspca_dev->cur_frame = &gspca_dev->frame[j]; | 305 | gspca_dev->cur_frame = &gspca_dev->frame[j]; |
306 | } | 306 | } |
307 | return; | ||
308 | } | 307 | } |
309 | EXPORT_SYMBOL(gspca_frame_add); | 308 | EXPORT_SYMBOL(gspca_frame_add); |
310 | 309 | ||
@@ -321,7 +320,7 @@ static int gspca_is_compressed(__u32 format) | |||
321 | return 0; | 320 | return 0; |
322 | } | 321 | } |
323 | 322 | ||
324 | static void *rvmalloc(unsigned long size) | 323 | static void *rvmalloc(long size) |
325 | { | 324 | { |
326 | void *mem; | 325 | void *mem; |
327 | unsigned long adr; | 326 | unsigned long adr; |
@@ -329,7 +328,7 @@ static void *rvmalloc(unsigned long size) | |||
329 | mem = vmalloc_32(size); | 328 | mem = vmalloc_32(size); |
330 | if (mem != NULL) { | 329 | if (mem != NULL) { |
331 | adr = (unsigned long) mem; | 330 | adr = (unsigned long) mem; |
332 | while ((long) size > 0) { | 331 | while (size > 0) { |
333 | SetPageReserved(vmalloc_to_page((void *) adr)); | 332 | SetPageReserved(vmalloc_to_page((void *) adr)); |
334 | adr += PAGE_SIZE; | 333 | adr += PAGE_SIZE; |
335 | size -= PAGE_SIZE; | 334 | size -= PAGE_SIZE; |
@@ -768,6 +767,7 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
768 | 767 | ||
769 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 768 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
770 | return -ERESTARTSYS; | 769 | return -ERESTARTSYS; |
770 | gspca_dev->usb_err = 0; | ||
771 | if (gspca_dev->present) | 771 | if (gspca_dev->present) |
772 | ret = gspca_dev->sd_desc->get_register(gspca_dev, reg); | 772 | ret = gspca_dev->sd_desc->get_register(gspca_dev, reg); |
773 | else | 773 | else |
@@ -791,6 +791,7 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
791 | 791 | ||
792 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 792 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
793 | return -ERESTARTSYS; | 793 | return -ERESTARTSYS; |
794 | gspca_dev->usb_err = 0; | ||
794 | if (gspca_dev->present) | 795 | if (gspca_dev->present) |
795 | ret = gspca_dev->sd_desc->set_register(gspca_dev, reg); | 796 | ret = gspca_dev->sd_desc->set_register(gspca_dev, reg); |
796 | else | 797 | else |
@@ -812,6 +813,7 @@ static int vidioc_g_chip_ident(struct file *file, void *priv, | |||
812 | 813 | ||
813 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 814 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
814 | return -ERESTARTSYS; | 815 | return -ERESTARTSYS; |
816 | gspca_dev->usb_err = 0; | ||
815 | if (gspca_dev->present) | 817 | if (gspca_dev->present) |
816 | ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); | 818 | ret = gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip); |
817 | else | 819 | else |
@@ -983,11 +985,40 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, | |||
983 | return -EINVAL; | 985 | return -EINVAL; |
984 | } | 986 | } |
985 | 987 | ||
988 | static int vidioc_enum_frameintervals(struct file *filp, void *priv, | ||
989 | struct v4l2_frmivalenum *fival) | ||
990 | { | ||
991 | struct gspca_dev *gspca_dev = priv; | ||
992 | int mode = wxh_to_mode(gspca_dev, fival->width, fival->height); | ||
993 | __u32 i; | ||
994 | |||
995 | if (gspca_dev->cam.mode_framerates == NULL || | ||
996 | gspca_dev->cam.mode_framerates[mode].nrates == 0) | ||
997 | return -EINVAL; | ||
998 | |||
999 | if (fival->pixel_format != | ||
1000 | gspca_dev->cam.cam_mode[mode].pixelformat) | ||
1001 | return -EINVAL; | ||
1002 | |||
1003 | for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) { | ||
1004 | if (fival->index == i) { | ||
1005 | fival->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
1006 | fival->discrete.numerator = 1; | ||
1007 | fival->discrete.denominator = | ||
1008 | gspca_dev->cam.mode_framerates[mode].rates[i]; | ||
1009 | return 0; | ||
1010 | } | ||
1011 | } | ||
1012 | |||
1013 | return -EINVAL; | ||
1014 | } | ||
1015 | |||
986 | static void gspca_release(struct video_device *vfd) | 1016 | static void gspca_release(struct video_device *vfd) |
987 | { | 1017 | { |
988 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); | 1018 | struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); |
989 | 1019 | ||
990 | PDEBUG(D_PROBE, "/dev/video%d released", gspca_dev->vdev.num); | 1020 | PDEBUG(D_PROBE, "%s released", |
1021 | video_device_node_name(&gspca_dev->vdev)); | ||
991 | 1022 | ||
992 | kfree(gspca_dev->usb_buf); | 1023 | kfree(gspca_dev->usb_buf); |
993 | kfree(gspca_dev); | 1024 | kfree(gspca_dev); |
@@ -1053,6 +1084,7 @@ static int dev_close(struct file *file) | |||
1053 | if (gspca_dev->capt_file == file) { | 1084 | if (gspca_dev->capt_file == file) { |
1054 | if (gspca_dev->streaming) { | 1085 | if (gspca_dev->streaming) { |
1055 | mutex_lock(&gspca_dev->usb_lock); | 1086 | mutex_lock(&gspca_dev->usb_lock); |
1087 | gspca_dev->usb_err = 0; | ||
1056 | gspca_stream_off(gspca_dev); | 1088 | gspca_stream_off(gspca_dev); |
1057 | mutex_unlock(&gspca_dev->usb_lock); | 1089 | mutex_unlock(&gspca_dev->usb_lock); |
1058 | } | 1090 | } |
@@ -1143,12 +1175,14 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
1143 | continue; | 1175 | continue; |
1144 | ctrls = &gspca_dev->sd_desc->ctrls[i]; | 1176 | ctrls = &gspca_dev->sd_desc->ctrls[i]; |
1145 | } | 1177 | } |
1178 | if (ctrls == NULL) | ||
1179 | return -EINVAL; | ||
1146 | } else { | 1180 | } else { |
1147 | ctrls = get_ctrl(gspca_dev, id); | 1181 | ctrls = get_ctrl(gspca_dev, id); |
1182 | if (ctrls == NULL) | ||
1183 | return -EINVAL; | ||
1148 | i = ctrls - gspca_dev->sd_desc->ctrls; | 1184 | i = ctrls - gspca_dev->sd_desc->ctrls; |
1149 | } | 1185 | } |
1150 | if (ctrls == NULL) | ||
1151 | return -EINVAL; | ||
1152 | memcpy(q_ctrl, ctrls, sizeof *q_ctrl); | 1186 | memcpy(q_ctrl, ctrls, sizeof *q_ctrl); |
1153 | if (gspca_dev->ctrl_inac & (1 << i)) | 1187 | if (gspca_dev->ctrl_inac & (1 << i)) |
1154 | q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; | 1188 | q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; |
@@ -1172,6 +1206,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1172 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); | 1206 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); |
1173 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1207 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1174 | return -ERESTARTSYS; | 1208 | return -ERESTARTSYS; |
1209 | gspca_dev->usb_err = 0; | ||
1175 | if (gspca_dev->present) | 1210 | if (gspca_dev->present) |
1176 | ret = ctrls->set(gspca_dev, ctrl->value); | 1211 | ret = ctrls->set(gspca_dev, ctrl->value); |
1177 | else | 1212 | else |
@@ -1193,6 +1228,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
1193 | 1228 | ||
1194 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1229 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1195 | return -ERESTARTSYS; | 1230 | return -ERESTARTSYS; |
1231 | gspca_dev->usb_err = 0; | ||
1196 | if (gspca_dev->present) | 1232 | if (gspca_dev->present) |
1197 | ret = ctrls->get(gspca_dev, &ctrl->value); | 1233 | ret = ctrls->get(gspca_dev, &ctrl->value); |
1198 | else | 1234 | else |
@@ -1307,6 +1343,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
1307 | /* stop streaming */ | 1343 | /* stop streaming */ |
1308 | if (gspca_dev->streaming) { | 1344 | if (gspca_dev->streaming) { |
1309 | mutex_lock(&gspca_dev->usb_lock); | 1345 | mutex_lock(&gspca_dev->usb_lock); |
1346 | gspca_dev->usb_err = 0; | ||
1310 | gspca_stream_off(gspca_dev); | 1347 | gspca_stream_off(gspca_dev); |
1311 | mutex_unlock(&gspca_dev->usb_lock); | 1348 | mutex_unlock(&gspca_dev->usb_lock); |
1312 | } | 1349 | } |
@@ -1398,6 +1435,7 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1398 | ret = -ERESTARTSYS; | 1435 | ret = -ERESTARTSYS; |
1399 | goto out; | 1436 | goto out; |
1400 | } | 1437 | } |
1438 | gspca_dev->usb_err = 0; | ||
1401 | gspca_stream_off(gspca_dev); | 1439 | gspca_stream_off(gspca_dev); |
1402 | mutex_unlock(&gspca_dev->usb_lock); | 1440 | mutex_unlock(&gspca_dev->usb_lock); |
1403 | 1441 | ||
@@ -1423,6 +1461,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, | |||
1423 | return -EINVAL; | 1461 | return -EINVAL; |
1424 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1462 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1425 | return -ERESTARTSYS; | 1463 | return -ERESTARTSYS; |
1464 | gspca_dev->usb_err = 0; | ||
1426 | if (gspca_dev->present) | 1465 | if (gspca_dev->present) |
1427 | ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); | 1466 | ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); |
1428 | else | 1467 | else |
@@ -1441,6 +1480,7 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, | |||
1441 | return -EINVAL; | 1480 | return -EINVAL; |
1442 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1481 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1443 | return -ERESTARTSYS; | 1482 | return -ERESTARTSYS; |
1483 | gspca_dev->usb_err = 0; | ||
1444 | if (gspca_dev->present) | 1484 | if (gspca_dev->present) |
1445 | ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); | 1485 | ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); |
1446 | else | 1486 | else |
@@ -1461,6 +1501,7 @@ static int vidioc_g_parm(struct file *filp, void *priv, | |||
1461 | 1501 | ||
1462 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1502 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1463 | return -ERESTARTSYS; | 1503 | return -ERESTARTSYS; |
1504 | gspca_dev->usb_err = 0; | ||
1464 | if (gspca_dev->present) | 1505 | if (gspca_dev->present) |
1465 | ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, | 1506 | ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, |
1466 | parm); | 1507 | parm); |
@@ -1490,6 +1531,7 @@ static int vidioc_s_parm(struct file *filp, void *priv, | |||
1490 | 1531 | ||
1491 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | 1532 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) |
1492 | return -ERESTARTSYS; | 1533 | return -ERESTARTSYS; |
1534 | gspca_dev->usb_err = 0; | ||
1493 | if (gspca_dev->present) | 1535 | if (gspca_dev->present) |
1494 | ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, | 1536 | ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, |
1495 | parm); | 1537 | parm); |
@@ -1613,7 +1655,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) | |||
1613 | size -= PAGE_SIZE; | 1655 | size -= PAGE_SIZE; |
1614 | } | 1656 | } |
1615 | 1657 | ||
1616 | vma->vm_ops = (struct vm_operations_struct *) &gspca_vm_ops; | 1658 | vma->vm_ops = &gspca_vm_ops; |
1617 | vma->vm_private_data = frame; | 1659 | vma->vm_private_data = frame; |
1618 | gspca_vm_open(vma); | 1660 | gspca_vm_open(vma); |
1619 | ret = 0; | 1661 | ret = 0; |
@@ -1661,6 +1703,7 @@ static int frame_wait(struct gspca_dev *gspca_dev, | |||
1661 | 1703 | ||
1662 | if (gspca_dev->sd_desc->dq_callback) { | 1704 | if (gspca_dev->sd_desc->dq_callback) { |
1663 | mutex_lock(&gspca_dev->usb_lock); | 1705 | mutex_lock(&gspca_dev->usb_lock); |
1706 | gspca_dev->usb_err = 0; | ||
1664 | if (gspca_dev->present) | 1707 | if (gspca_dev->present) |
1665 | gspca_dev->sd_desc->dq_callback(gspca_dev); | 1708 | gspca_dev->sd_desc->dq_callback(gspca_dev); |
1666 | mutex_unlock(&gspca_dev->usb_lock); | 1709 | mutex_unlock(&gspca_dev->usb_lock); |
@@ -1973,6 +2016,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { | |||
1973 | .vidioc_g_parm = vidioc_g_parm, | 2016 | .vidioc_g_parm = vidioc_g_parm, |
1974 | .vidioc_s_parm = vidioc_s_parm, | 2017 | .vidioc_s_parm = vidioc_s_parm, |
1975 | .vidioc_enum_framesizes = vidioc_enum_framesizes, | 2018 | .vidioc_enum_framesizes = vidioc_enum_framesizes, |
2019 | .vidioc_enum_frameintervals = vidioc_enum_frameintervals, | ||
1976 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2020 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1977 | .vidioc_g_register = vidioc_g_register, | 2021 | .vidioc_g_register = vidioc_g_register, |
1978 | .vidioc_s_register = vidioc_s_register, | 2022 | .vidioc_s_register = vidioc_s_register, |
@@ -1988,7 +2032,6 @@ static struct video_device gspca_template = { | |||
1988 | .fops = &dev_fops, | 2032 | .fops = &dev_fops, |
1989 | .ioctl_ops = &dev_ioctl_ops, | 2033 | .ioctl_ops = &dev_ioctl_ops, |
1990 | .release = gspca_release, | 2034 | .release = gspca_release, |
1991 | .minor = -1, | ||
1992 | }; | 2035 | }; |
1993 | 2036 | ||
1994 | /* | 2037 | /* |
@@ -2049,9 +2092,6 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
2049 | ret = sd_desc->init(gspca_dev); | 2092 | ret = sd_desc->init(gspca_dev); |
2050 | if (ret < 0) | 2093 | if (ret < 0) |
2051 | goto out; | 2094 | goto out; |
2052 | ret = gspca_set_alt0(gspca_dev); | ||
2053 | if (ret < 0) | ||
2054 | goto out; | ||
2055 | gspca_set_default_mode(gspca_dev); | 2095 | gspca_set_default_mode(gspca_dev); |
2056 | 2096 | ||
2057 | mutex_init(&gspca_dev->usb_lock); | 2097 | mutex_init(&gspca_dev->usb_lock); |
@@ -2073,7 +2113,7 @@ int gspca_dev_probe(struct usb_interface *intf, | |||
2073 | } | 2113 | } |
2074 | 2114 | ||
2075 | usb_set_intfdata(intf, gspca_dev); | 2115 | usb_set_intfdata(intf, gspca_dev); |
2076 | PDEBUG(D_PROBE, "/dev/video%d created", gspca_dev->vdev.num); | 2116 | PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev)); |
2077 | return 0; | 2117 | return 0; |
2078 | out: | 2118 | out: |
2079 | kfree(gspca_dev->usb_buf); | 2119 | kfree(gspca_dev->usb_buf); |
@@ -2092,7 +2132,8 @@ void gspca_disconnect(struct usb_interface *intf) | |||
2092 | { | 2132 | { |
2093 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | 2133 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); |
2094 | 2134 | ||
2095 | PDEBUG(D_PROBE, "/dev/video%d disconnect", gspca_dev->vdev.num); | 2135 | PDEBUG(D_PROBE, "%s disconnect", |
2136 | video_device_node_name(&gspca_dev->vdev)); | ||
2096 | mutex_lock(&gspca_dev->usb_lock); | 2137 | mutex_lock(&gspca_dev->usb_lock); |
2097 | gspca_dev->present = 0; | 2138 | gspca_dev->present = 0; |
2098 | 2139 | ||
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 181617355ec..59c7941da99 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -45,11 +45,20 @@ extern int gspca_debug; | |||
45 | /* image transfers */ | 45 | /* image transfers */ |
46 | #define MAX_NURBS 4 /* max number of URBs */ | 46 | #define MAX_NURBS 4 /* max number of URBs */ |
47 | 47 | ||
48 | |||
49 | /* used to list framerates supported by a camera mode (resolution) */ | ||
50 | struct framerates { | ||
51 | int *rates; | ||
52 | int nrates; | ||
53 | }; | ||
54 | |||
48 | /* device information - set at probe time */ | 55 | /* device information - set at probe time */ |
49 | struct cam { | 56 | struct cam { |
50 | int bulk_size; /* buffer size when image transfer by bulk */ | 57 | int bulk_size; /* buffer size when image transfer by bulk */ |
51 | const struct v4l2_pix_format *cam_mode; /* size nmodes */ | 58 | const struct v4l2_pix_format *cam_mode; /* size nmodes */ |
52 | char nmodes; | 59 | char nmodes; |
60 | const struct framerates *mode_framerates; /* must have size nmode, | ||
61 | * just like cam_mode */ | ||
53 | __u8 bulk_nurbs; /* number of URBs in bulk mode | 62 | __u8 bulk_nurbs; /* number of URBs in bulk mode |
54 | * - cannot be > MAX_NURBS | 63 | * - cannot be > MAX_NURBS |
55 | * - when 0 and bulk_size != 0 means | 64 | * - when 0 and bulk_size != 0 means |
@@ -171,6 +180,7 @@ struct gspca_dev { | |||
171 | struct mutex usb_lock; /* usb exchange protection */ | 180 | struct mutex usb_lock; /* usb exchange protection */ |
172 | struct mutex read_lock; /* read protection */ | 181 | struct mutex read_lock; /* read protection */ |
173 | struct mutex queue_lock; /* ISOC queue protection */ | 182 | struct mutex queue_lock; /* ISOC queue protection */ |
183 | int usb_err; /* USB error - protected by usb_lock */ | ||
174 | #ifdef CONFIG_PM | 184 | #ifdef CONFIG_PM |
175 | char frozen; /* suspend - resume */ | 185 | char frozen; /* suspend - resume */ |
176 | #endif | 186 | #endif |
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index 844fc1d886d..4294c75e3b1 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/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) | |||
81 | return (err < 0) ? err : 0; | 81 | return (err < 0) ? err : 0; |
82 | } | 82 | } |
83 | 83 | ||
84 | int m5602_wait_for_i2c(struct sd *sd) | 84 | static int m5602_wait_for_i2c(struct sd *sd) |
85 | { | 85 | { |
86 | int err; | 86 | int err; |
87 | u8 data; | 87 | u8 data; |
@@ -388,7 +388,7 @@ static int m5602_probe(struct usb_interface *intf, | |||
388 | THIS_MODULE); | 388 | THIS_MODULE); |
389 | } | 389 | } |
390 | 390 | ||
391 | void m5602_disconnect(struct usb_interface *intf) | 391 | static void m5602_disconnect(struct usb_interface *intf) |
392 | { | 392 | { |
393 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | 393 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); |
394 | struct sd *sd = (struct sd *) gspca_dev; | 394 | struct sd *sd = (struct sd *) gspca_dev; |
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index c2739d6605a..923cdd5f7a6 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -439,7 +439,7 @@ int ov9650_start(struct sd *sd) | |||
439 | err = m5602_write_bridge(sd, res_init_ov9650[i][1], | 439 | err = m5602_write_bridge(sd, res_init_ov9650[i][1], |
440 | res_init_ov9650[i][2]); | 440 | res_init_ov9650[i][2]); |
441 | else if (res_init_ov9650[i][0] == SENSOR) { | 441 | else if (res_init_ov9650[i][0] == SENSOR) { |
442 | u8 data = res_init_ov9650[i][2]; | 442 | data = res_init_ov9650[i][2]; |
443 | err = m5602_write_sensor(sd, | 443 | err = m5602_write_sensor(sd, |
444 | res_init_ov9650[i][1], &data, 1); | 444 | res_init_ov9650[i][1], &data, 1); |
445 | } | 445 | } |
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index a27afeb6f39..aa2f3c7e2cb 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
@@ -525,7 +525,10 @@ static int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
525 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | 525 | err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); |
526 | if (err < 0) | 526 | if (err < 0) |
527 | return err; | 527 | return err; |
528 | data = (data & 0xfe) | !val; | 528 | if (val) |
529 | data &= 0xfe; | ||
530 | else | ||
531 | data |= 0x01; | ||
529 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); | 532 | err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1); |
530 | return err; | 533 | return err; |
531 | } | 534 | } |
@@ -570,7 +573,10 @@ static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
570 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | 573 | err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); |
571 | if (err < 0) | 574 | if (err < 0) |
572 | return err; | 575 | return err; |
573 | data = (data & 0xfe) | !val; | 576 | if (val) |
577 | data &= 0xfe; | ||
578 | else | ||
579 | data |= 0x01; | ||
574 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); | 580 | err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1); |
575 | return err; | 581 | return err; |
576 | } | 582 | } |
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 126d968dd9e..9154870e07d 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c | |||
@@ -67,7 +67,7 @@ MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); | |||
67 | MODULE_LICENSE("GPL"); | 67 | MODULE_LICENSE("GPL"); |
68 | 68 | ||
69 | /* global parameters */ | 69 | /* global parameters */ |
70 | int force_sensor_type = -1; | 70 | static int force_sensor_type = -1; |
71 | module_param(force_sensor_type, int, 0644); | 71 | module_param(force_sensor_type, int, 0644); |
72 | MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)"); | 72 | MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)"); |
73 | 73 | ||
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index ad9ec339981..b4f96573124 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -1982,7 +1982,7 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | |||
1982 | { | 1982 | { |
1983 | int ret; | 1983 | int ret; |
1984 | 1984 | ||
1985 | *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value); | 1985 | *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value); |
1986 | 1986 | ||
1987 | ret = usb_control_msg(sd->gspca_dev.dev, | 1987 | ret = usb_control_msg(sd->gspca_dev.dev, |
1988 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | 1988 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), |
@@ -2021,9 +2021,9 @@ static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) | |||
2021 | if (rc < 0) | 2021 | if (rc < 0) |
2022 | return rc; | 2022 | return rc; |
2023 | 2023 | ||
2024 | do | 2024 | do { |
2025 | rc = reg_r(sd, R511_I2C_CTL); | 2025 | rc = reg_r(sd, R511_I2C_CTL); |
2026 | while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ | 2026 | } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ |
2027 | 2027 | ||
2028 | if (rc < 0) | 2028 | if (rc < 0) |
2029 | return rc; | 2029 | return rc; |
@@ -2055,9 +2055,9 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2055 | if (rc < 0) | 2055 | if (rc < 0) |
2056 | return rc; | 2056 | return rc; |
2057 | 2057 | ||
2058 | do | 2058 | do { |
2059 | rc = reg_r(sd, R511_I2C_CTL); | 2059 | rc = reg_r(sd, R511_I2C_CTL); |
2060 | while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ | 2060 | } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ |
2061 | 2061 | ||
2062 | if (rc < 0) | 2062 | if (rc < 0) |
2063 | return rc; | 2063 | return rc; |
@@ -2081,9 +2081,9 @@ static int ov511_i2c_r(struct sd *sd, __u8 reg) | |||
2081 | if (rc < 0) | 2081 | if (rc < 0) |
2082 | return rc; | 2082 | return rc; |
2083 | 2083 | ||
2084 | do | 2084 | do { |
2085 | rc = reg_r(sd, R511_I2C_CTL); | 2085 | rc = reg_r(sd, R511_I2C_CTL); |
2086 | while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ | 2086 | } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ |
2087 | 2087 | ||
2088 | if (rc < 0) | 2088 | if (rc < 0) |
2089 | return rc; | 2089 | return rc; |
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 74acceea809..de0b66c4b56 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c | |||
@@ -90,6 +90,9 @@ struct sd { | |||
90 | unsigned char autogain; | 90 | unsigned char autogain; |
91 | __u8 hflip; | 91 | __u8 hflip; |
92 | __u8 vflip; | 92 | __u8 vflip; |
93 | u8 flags; | ||
94 | #define FL_HFLIP 0x01 /* mirrored by default */ | ||
95 | #define FL_VFLIP 0x02 /* vertical flipped by default */ | ||
93 | 96 | ||
94 | u8 sof_read; | 97 | u8 sof_read; |
95 | u8 autogain_ignore_frames; | 98 | u8 autogain_ignore_frames; |
@@ -552,6 +555,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
552 | sd->autogain = AUTOGAIN_DEF; | 555 | sd->autogain = AUTOGAIN_DEF; |
553 | sd->hflip = HFLIP_DEF; | 556 | sd->hflip = HFLIP_DEF; |
554 | sd->vflip = VFLIP_DEF; | 557 | sd->vflip = VFLIP_DEF; |
558 | sd->flags = id->driver_info; | ||
555 | return 0; | 559 | return 0; |
556 | } | 560 | } |
557 | 561 | ||
@@ -708,10 +712,17 @@ static int sethvflip(struct gspca_dev *gspca_dev) | |||
708 | { | 712 | { |
709 | struct sd *sd = (struct sd *) gspca_dev; | 713 | struct sd *sd = (struct sd *) gspca_dev; |
710 | int ret; | 714 | int ret; |
711 | __u8 data; | 715 | u8 data, hflip, vflip; |
716 | |||
717 | hflip = sd->hflip; | ||
718 | if (sd->flags & FL_HFLIP) | ||
719 | hflip = !hflip; | ||
720 | vflip = sd->vflip; | ||
721 | if (sd->flags & FL_VFLIP) | ||
722 | vflip = !vflip; | ||
712 | 723 | ||
713 | ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ | 724 | ret = reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ |
714 | data = (sd->hflip ? 0x08 : 0x00) | (sd->vflip ? 0x04 : 0x00); | 725 | data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00); |
715 | if (0 <= ret) | 726 | if (0 <= ret) |
716 | ret = reg_w(gspca_dev, 0x21, data); | 727 | ret = reg_w(gspca_dev, 0x21, data); |
717 | /* load registers to sensor (Bit 0, auto clear) */ | 728 | /* load registers to sensor (Bit 0, auto clear) */ |
@@ -1218,15 +1229,15 @@ static struct sd_desc sd_desc = { | |||
1218 | }; | 1229 | }; |
1219 | 1230 | ||
1220 | /* -- module initialisation -- */ | 1231 | /* -- module initialisation -- */ |
1221 | static __devinitdata struct usb_device_id device_table[] = { | 1232 | static const struct usb_device_id device_table[] __devinitconst = { |
1222 | {USB_DEVICE(0x06f8, 0x3009)}, | 1233 | {USB_DEVICE(0x06f8, 0x3009)}, |
1223 | {USB_DEVICE(0x093a, 0x2620)}, | 1234 | {USB_DEVICE(0x093a, 0x2620)}, |
1224 | {USB_DEVICE(0x093a, 0x2621)}, | 1235 | {USB_DEVICE(0x093a, 0x2621)}, |
1225 | {USB_DEVICE(0x093a, 0x2622)}, | 1236 | {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, |
1226 | {USB_DEVICE(0x093a, 0x2624)}, | 1237 | {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP}, |
1227 | {USB_DEVICE(0x093a, 0x2626)}, | 1238 | {USB_DEVICE(0x093a, 0x2626)}, |
1228 | {USB_DEVICE(0x093a, 0x2628)}, | 1239 | {USB_DEVICE(0x093a, 0x2628)}, |
1229 | {USB_DEVICE(0x093a, 0x2629)}, | 1240 | {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP}, |
1230 | {USB_DEVICE(0x093a, 0x262a)}, | 1241 | {USB_DEVICE(0x093a, 0x262a)}, |
1231 | {USB_DEVICE(0x093a, 0x262c)}, | 1242 | {USB_DEVICE(0x093a, 0x262c)}, |
1232 | {} | 1243 | {} |
@@ -1234,7 +1245,7 @@ static __devinitdata struct usb_device_id device_table[] = { | |||
1234 | MODULE_DEVICE_TABLE(usb, device_table); | 1245 | MODULE_DEVICE_TABLE(usb, device_table); |
1235 | 1246 | ||
1236 | /* -- device connect -- */ | 1247 | /* -- device connect -- */ |
1237 | static int sd_probe(struct usb_interface *intf, | 1248 | static int __devinit sd_probe(struct usb_interface *intf, |
1238 | const struct usb_device_id *id) | 1249 | const struct usb_device_id *id) |
1239 | { | 1250 | { |
1240 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | 1251 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), |
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index e5697a6345e..42cfcdfd8f4 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -863,7 +863,7 @@ static struct sd_desc sd_desc = { | |||
863 | }; | 863 | }; |
864 | 864 | ||
865 | /* -- module initialisation -- */ | 865 | /* -- module initialisation -- */ |
866 | static __devinitdata struct usb_device_id device_table[] = { | 866 | static const struct usb_device_id device_table[] __devinitconst = { |
867 | {USB_DEVICE(0x093a, 0x2600)}, | 867 | {USB_DEVICE(0x093a, 0x2600)}, |
868 | {USB_DEVICE(0x093a, 0x2601)}, | 868 | {USB_DEVICE(0x093a, 0x2601)}, |
869 | {USB_DEVICE(0x093a, 0x2603)}, | 869 | {USB_DEVICE(0x093a, 0x2603)}, |
@@ -875,7 +875,7 @@ static __devinitdata struct usb_device_id device_table[] = { | |||
875 | MODULE_DEVICE_TABLE(usb, device_table); | 875 | MODULE_DEVICE_TABLE(usb, device_table); |
876 | 876 | ||
877 | /* -- device connect -- */ | 877 | /* -- device connect -- */ |
878 | static int sd_probe(struct usb_interface *intf, | 878 | static int __devinit sd_probe(struct usb_interface *intf, |
879 | const struct usb_device_id *id) | 879 | const struct usb_device_id *id) |
880 | { | 880 | { |
881 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | 881 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), |
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index b1944a7cbb0..4cff8035614 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c | |||
@@ -1158,7 +1158,7 @@ static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) | |||
1158 | return i2c_w(gspca_dev, row); | 1158 | return i2c_w(gspca_dev, row); |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) | 1161 | static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) |
1162 | { | 1162 | { |
1163 | struct sd *sd = (struct sd *) gspca_dev; | 1163 | struct sd *sd = (struct sd *) gspca_dev; |
1164 | u8 row[8]; | 1164 | u8 row[8]; |
@@ -1183,7 +1183,7 @@ int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) | |||
1183 | return 0; | 1183 | return 0; |
1184 | } | 1184 | } |
1185 | 1185 | ||
1186 | int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) | 1186 | static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) |
1187 | { | 1187 | { |
1188 | struct sd *sd = (struct sd *) gspca_dev; | 1188 | struct sd *sd = (struct sd *) gspca_dev; |
1189 | u8 row[8]; | 1189 | u8 row[8]; |
@@ -1476,8 +1476,9 @@ static int sn9c20x_input_init(struct gspca_dev *gspca_dev) | |||
1476 | if (input_register_device(sd->input_dev)) | 1476 | if (input_register_device(sd->input_dev)) |
1477 | return -EINVAL; | 1477 | return -EINVAL; |
1478 | 1478 | ||
1479 | sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%d", | 1479 | sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%s-%s", |
1480 | gspca_dev->vdev.minor); | 1480 | gspca_dev->dev->bus->bus_name, |
1481 | gspca_dev->dev->devpath); | ||
1481 | 1482 | ||
1482 | if (IS_ERR(sd->input_task)) | 1483 | if (IS_ERR(sd->input_task)) |
1483 | return -EINVAL; | 1484 | return -EINVAL; |
@@ -2174,8 +2175,7 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) | |||
2174 | } | 2175 | } |
2175 | 2176 | ||
2176 | #define HW_WIN(mode, hstart, vstart) \ | 2177 | #define HW_WIN(mode, hstart, vstart) \ |
2177 | ((const u8 []){hstart & 0xff, hstart >> 8, \ | 2178 | ((const u8 []){hstart, 0, vstart, 0, \ |
2178 | vstart & 0xff, vstart >> 8, \ | ||
2179 | (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \ | 2179 | (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \ |
2180 | (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)}) | 2180 | (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)}) |
2181 | 2181 | ||
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 5be95bc6513..ddff2b5ee5c 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -1226,7 +1226,7 @@ static const struct sd_desc sd_desc = { | |||
1226 | .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge | 1226 | .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge |
1227 | 1227 | ||
1228 | 1228 | ||
1229 | static __devinitdata struct usb_device_id device_table[] = { | 1229 | static const struct usb_device_id device_table[] __devinitconst = { |
1230 | {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */ | 1230 | {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */ |
1231 | {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */ | 1231 | {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */ |
1232 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 1232 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
@@ -1257,7 +1257,7 @@ static __devinitdata struct usb_device_id device_table[] = { | |||
1257 | MODULE_DEVICE_TABLE(usb, device_table); | 1257 | MODULE_DEVICE_TABLE(usb, device_table); |
1258 | 1258 | ||
1259 | /* -- device connect -- */ | 1259 | /* -- device connect -- */ |
1260 | static int sd_probe(struct usb_interface *intf, | 1260 | static int __devinit sd_probe(struct usb_interface *intf, |
1261 | const struct usb_device_id *id) | 1261 | const struct usb_device_id *id) |
1262 | { | 1262 | { |
1263 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | 1263 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), |
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index ab28cc23e41..39257e4e074 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c | |||
@@ -685,7 +685,7 @@ static struct sd_desc sd_desc = { | |||
685 | }; | 685 | }; |
686 | 686 | ||
687 | /* -- module initialisation -- */ | 687 | /* -- module initialisation -- */ |
688 | static __devinitdata struct usb_device_id device_table[] = { | 688 | static const struct usb_device_id device_table[] __devinitconst = { |
689 | {USB_DEVICE(0x06e1, 0xa190)}, | 689 | {USB_DEVICE(0x06e1, 0xa190)}, |
690 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 | 690 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 |
691 | {USB_DEVICE(0x0733, 0x0430)}, */ | 691 | {USB_DEVICE(0x0733, 0x0430)}, */ |
@@ -696,7 +696,7 @@ static __devinitdata struct usb_device_id device_table[] = { | |||
696 | MODULE_DEVICE_TABLE(usb, device_table); | 696 | MODULE_DEVICE_TABLE(usb, device_table); |
697 | 697 | ||
698 | /* -- device connect -- */ | 698 | /* -- device connect -- */ |
699 | static int sd_probe(struct usb_interface *intf, | 699 | static int __devinit sd_probe(struct usb_interface *intf, |
700 | const struct usb_device_id *id) | 700 | const struct usb_device_id *id) |
701 | { | 701 | { |
702 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | 702 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), |
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 8e23320d7ab..2e2935532d9 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c | |||
@@ -126,12 +126,14 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
126 | }; | 126 | }; |
127 | 127 | ||
128 | /* -- read a register -- */ | 128 | /* -- read a register -- */ |
129 | static int reg_r(struct gspca_dev *gspca_dev, | 129 | static u8 reg_r(struct gspca_dev *gspca_dev, |
130 | __u16 index) | 130 | __u16 index) |
131 | { | 131 | { |
132 | struct usb_device *dev = gspca_dev->dev; | 132 | struct usb_device *dev = gspca_dev->dev; |
133 | int ret; | 133 | int ret; |
134 | 134 | ||
135 | if (gspca_dev->usb_err < 0) | ||
136 | return 0; | ||
135 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 137 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
136 | 0x00, | 138 | 0x00, |
137 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 139 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
@@ -141,18 +143,21 @@ static int reg_r(struct gspca_dev *gspca_dev, | |||
141 | 500); | 143 | 500); |
142 | if (ret < 0) { | 144 | if (ret < 0) { |
143 | PDEBUG(D_ERR, "reg_r err %d", ret); | 145 | PDEBUG(D_ERR, "reg_r err %d", ret); |
144 | return ret; | 146 | gspca_dev->usb_err = ret; |
147 | return 0; | ||
145 | } | 148 | } |
146 | return gspca_dev->usb_buf[0]; | 149 | return gspca_dev->usb_buf[0]; |
147 | } | 150 | } |
148 | 151 | ||
149 | /* -- write a register -- */ | 152 | /* -- write a register -- */ |
150 | static int reg_w(struct gspca_dev *gspca_dev, | 153 | static void reg_w(struct gspca_dev *gspca_dev, |
151 | __u16 index, __u16 value) | 154 | __u16 index, __u16 value) |
152 | { | 155 | { |
153 | struct usb_device *dev = gspca_dev->dev; | 156 | struct usb_device *dev = gspca_dev->dev; |
154 | int ret; | 157 | int ret; |
155 | 158 | ||
159 | if (gspca_dev->usb_err < 0) | ||
160 | return; | ||
156 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 161 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
157 | 0x01, | 162 | 0x01, |
158 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 163 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
@@ -161,13 +166,14 @@ static int reg_w(struct gspca_dev *gspca_dev, | |||
161 | NULL, | 166 | NULL, |
162 | 0, | 167 | 0, |
163 | 500); | 168 | 500); |
164 | if (ret < 0) | 169 | if (ret < 0) { |
165 | PDEBUG(D_ERR, "reg_w err %d", ret); | 170 | PDEBUG(D_ERR, "reg_w err %d", ret); |
166 | return ret; | 171 | gspca_dev->usb_err = ret; |
172 | } | ||
167 | } | 173 | } |
168 | 174 | ||
169 | /* -- get a bulk value (4 bytes) -- */ | 175 | /* -- get a bulk value (4 bytes) -- */ |
170 | static int rcv_val(struct gspca_dev *gspca_dev, | 176 | static void rcv_val(struct gspca_dev *gspca_dev, |
171 | int ads) | 177 | int ads) |
172 | { | 178 | { |
173 | struct usb_device *dev = gspca_dev->dev; | 179 | struct usb_device *dev = gspca_dev->dev; |
@@ -182,17 +188,22 @@ static int rcv_val(struct gspca_dev *gspca_dev, | |||
182 | reg_w(gspca_dev, 0x63a, 0); | 188 | reg_w(gspca_dev, 0x63a, 0); |
183 | reg_w(gspca_dev, 0x63b, 0); | 189 | reg_w(gspca_dev, 0x63b, 0); |
184 | reg_w(gspca_dev, 0x630, 5); | 190 | reg_w(gspca_dev, 0x630, 5); |
191 | if (gspca_dev->usb_err < 0) | ||
192 | return; | ||
185 | ret = usb_bulk_msg(dev, | 193 | ret = usb_bulk_msg(dev, |
186 | usb_rcvbulkpipe(dev, 0x05), | 194 | usb_rcvbulkpipe(dev, 0x05), |
187 | gspca_dev->usb_buf, | 195 | gspca_dev->usb_buf, |
188 | 4, /* length */ | 196 | 4, /* length */ |
189 | &alen, | 197 | &alen, |
190 | 500); /* timeout in milliseconds */ | 198 | 500); /* timeout in milliseconds */ |
191 | return ret; | 199 | if (ret < 0) { |
200 | PDEBUG(D_ERR, "rcv_val err %d", ret); | ||
201 | gspca_dev->usb_err = ret; | ||
202 | } | ||
192 | } | 203 | } |
193 | 204 | ||
194 | /* -- send a bulk value -- */ | 205 | /* -- send a bulk value -- */ |
195 | static int snd_val(struct gspca_dev *gspca_dev, | 206 | static void snd_val(struct gspca_dev *gspca_dev, |
196 | int ads, | 207 | int ads, |
197 | unsigned int val) | 208 | unsigned int val) |
198 | { | 209 | { |
@@ -201,16 +212,9 @@ static int snd_val(struct gspca_dev *gspca_dev, | |||
201 | __u8 seq = 0; | 212 | __u8 seq = 0; |
202 | 213 | ||
203 | if (ads == 0x003f08) { | 214 | if (ads == 0x003f08) { |
204 | ret = reg_r(gspca_dev, 0x0704); | 215 | reg_r(gspca_dev, 0x0704); |
205 | if (ret < 0) | 216 | seq = reg_r(gspca_dev, 0x0705); |
206 | goto ko; | 217 | reg_r(gspca_dev, 0x0650); |
207 | ret = reg_r(gspca_dev, 0x0705); | ||
208 | if (ret < 0) | ||
209 | goto ko; | ||
210 | seq = ret; /* keep the sequence number */ | ||
211 | ret = reg_r(gspca_dev, 0x0650); | ||
212 | if (ret < 0) | ||
213 | goto ko; | ||
214 | reg_w(gspca_dev, 0x654, seq); | 218 | reg_w(gspca_dev, 0x654, seq); |
215 | } else { | 219 | } else { |
216 | reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff); | 220 | reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff); |
@@ -223,6 +227,8 @@ static int snd_val(struct gspca_dev *gspca_dev, | |||
223 | reg_w(gspca_dev, 0x65a, 0); | 227 | reg_w(gspca_dev, 0x65a, 0); |
224 | reg_w(gspca_dev, 0x65b, 0); | 228 | reg_w(gspca_dev, 0x65b, 0); |
225 | reg_w(gspca_dev, 0x650, 5); | 229 | reg_w(gspca_dev, 0x650, 5); |
230 | if (gspca_dev->usb_err < 0) | ||
231 | return; | ||
226 | gspca_dev->usb_buf[0] = val >> 24; | 232 | gspca_dev->usb_buf[0] = val >> 24; |
227 | gspca_dev->usb_buf[1] = val >> 16; | 233 | gspca_dev->usb_buf[1] = val >> 16; |
228 | gspca_dev->usb_buf[2] = val >> 8; | 234 | gspca_dev->usb_buf[2] = val >> 8; |
@@ -233,24 +239,23 @@ static int snd_val(struct gspca_dev *gspca_dev, | |||
233 | 4, | 239 | 4, |
234 | &alen, | 240 | &alen, |
235 | 500); /* timeout in milliseconds */ | 241 | 500); /* timeout in milliseconds */ |
236 | if (ret < 0) | 242 | if (ret < 0) { |
237 | goto ko; | 243 | PDEBUG(D_ERR, "snd_val err %d", ret); |
238 | if (ads == 0x003f08) { | 244 | gspca_dev->usb_err = ret; |
239 | seq += 4; | 245 | } else { |
240 | seq &= 0x3f; | 246 | if (ads == 0x003f08) { |
241 | reg_w(gspca_dev, 0x705, seq); | 247 | seq += 4; |
248 | seq &= 0x3f; | ||
249 | reg_w(gspca_dev, 0x705, seq); | ||
250 | } | ||
242 | } | 251 | } |
243 | return ret; | ||
244 | ko: | ||
245 | PDEBUG(D_ERR, "snd_val err %d", ret); | ||
246 | return ret; | ||
247 | } | 252 | } |
248 | 253 | ||
249 | /* set a camera parameter */ | 254 | /* set a camera parameter */ |
250 | static int set_par(struct gspca_dev *gspca_dev, | 255 | static void set_par(struct gspca_dev *gspca_dev, |
251 | int parval) | 256 | int parval) |
252 | { | 257 | { |
253 | return snd_val(gspca_dev, 0x003f08, parval); | 258 | snd_val(gspca_dev, 0x003f08, parval); |
254 | } | 259 | } |
255 | 260 | ||
256 | static void setbrightness(struct gspca_dev *gspca_dev) | 261 | static void setbrightness(struct gspca_dev *gspca_dev) |
@@ -311,18 +316,18 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
311 | /* this function is called at probe and resume time */ | 316 | /* this function is called at probe and resume time */ |
312 | static int sd_init(struct gspca_dev *gspca_dev) | 317 | static int sd_init(struct gspca_dev *gspca_dev) |
313 | { | 318 | { |
314 | int ret; | 319 | u8 ret; |
315 | 320 | ||
316 | /* check if the device responds */ | 321 | /* check if the device responds */ |
317 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); | 322 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); |
318 | ret = reg_r(gspca_dev, 0x0740); | 323 | ret = reg_r(gspca_dev, 0x0740); |
319 | if (ret < 0) | 324 | if (gspca_dev->usb_err >= 0) { |
320 | return ret; | 325 | if (ret != 0xff) { |
321 | if (ret != 0xff) { | 326 | PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret); |
322 | PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret); | 327 | gspca_dev->usb_err = -EIO; |
323 | return -1; | 328 | } |
324 | } | 329 | } |
325 | return 0; | 330 | return gspca_dev->usb_err; |
326 | } | 331 | } |
327 | 332 | ||
328 | /* -- start the camera -- */ | 333 | /* -- start the camera -- */ |
@@ -357,15 +362,12 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
357 | if (ret < 0) { | 362 | if (ret < 0) { |
358 | PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed", | 363 | PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed", |
359 | gspca_dev->iface, gspca_dev->alt); | 364 | gspca_dev->iface, gspca_dev->alt); |
365 | gspca_dev->usb_err = ret; | ||
360 | goto out; | 366 | goto out; |
361 | } | 367 | } |
362 | ret = reg_r(gspca_dev, 0x0630); | 368 | reg_r(gspca_dev, 0x0630); |
363 | if (ret < 0) | ||
364 | goto out; | ||
365 | rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ | 369 | rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ |
366 | ret = reg_r(gspca_dev, 0x0650); | 370 | reg_r(gspca_dev, 0x0650); |
367 | if (ret < 0) | ||
368 | goto out; | ||
369 | snd_val(gspca_dev, 0x000020, 0xffffffff); | 371 | snd_val(gspca_dev, 0x000020, 0xffffffff); |
370 | reg_w(gspca_dev, 0x0620, 0); | 372 | reg_w(gspca_dev, 0x0620, 0); |
371 | reg_w(gspca_dev, 0x0630, 0); | 373 | reg_w(gspca_dev, 0x0630, 0); |
@@ -384,11 +386,11 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
384 | /* start the video flow */ | 386 | /* start the video flow */ |
385 | set_par(gspca_dev, 0x01000000); | 387 | set_par(gspca_dev, 0x01000000); |
386 | set_par(gspca_dev, 0x01000000); | 388 | set_par(gspca_dev, 0x01000000); |
387 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); | 389 | if (gspca_dev->usb_err >= 0) |
388 | return 0; | 390 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", |
391 | gspca_dev->alt); | ||
389 | out: | 392 | out: |
390 | PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret); | 393 | return gspca_dev->usb_err; |
391 | return ret; | ||
392 | } | 394 | } |
393 | 395 | ||
394 | static void sd_stopN(struct gspca_dev *gspca_dev) | 396 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -456,7 +458,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | |||
456 | sd->brightness = val; | 458 | sd->brightness = val; |
457 | if (gspca_dev->streaming) | 459 | if (gspca_dev->streaming) |
458 | setbrightness(gspca_dev); | 460 | setbrightness(gspca_dev); |
459 | return 0; | 461 | return gspca_dev->usb_err; |
460 | } | 462 | } |
461 | 463 | ||
462 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | 464 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -474,7 +476,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | |||
474 | sd->contrast = val; | 476 | sd->contrast = val; |
475 | if (gspca_dev->streaming) | 477 | if (gspca_dev->streaming) |
476 | setcontrast(gspca_dev); | 478 | setcontrast(gspca_dev); |
477 | return 0; | 479 | return gspca_dev->usb_err; |
478 | } | 480 | } |
479 | 481 | ||
480 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | 482 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -492,7 +494,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | |||
492 | sd->colors = val; | 494 | sd->colors = val; |
493 | if (gspca_dev->streaming) | 495 | if (gspca_dev->streaming) |
494 | setcolors(gspca_dev); | 496 | setcolors(gspca_dev); |
495 | return 0; | 497 | return gspca_dev->usb_err; |
496 | } | 498 | } |
497 | 499 | ||
498 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | 500 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -510,7 +512,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | |||
510 | sd->lightfreq = val; | 512 | sd->lightfreq = val; |
511 | if (gspca_dev->streaming) | 513 | if (gspca_dev->streaming) |
512 | setfreq(gspca_dev); | 514 | setfreq(gspca_dev); |
513 | return 0; | 515 | return gspca_dev->usb_err; |
514 | } | 516 | } |
515 | 517 | ||
516 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | 518 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -552,7 +554,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, | |||
552 | sd->quality = jcomp->quality; | 554 | sd->quality = jcomp->quality; |
553 | if (gspca_dev->streaming) | 555 | if (gspca_dev->streaming) |
554 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 556 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
555 | return 0; | 557 | return gspca_dev->usb_err; |
556 | } | 558 | } |
557 | 559 | ||
558 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 560 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, |
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 72bf3b4f0a3..716df6b15fc 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -460,13 +460,17 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
460 | u16 index, | 460 | u16 index, |
461 | u16 len) | 461 | u16 len) |
462 | { | 462 | { |
463 | int ret; | ||
464 | |||
463 | #ifdef GSPCA_DEBUG | 465 | #ifdef GSPCA_DEBUG |
464 | if (len > USB_BUF_SZ) { | 466 | if (len > USB_BUF_SZ) { |
465 | err("reg_r: buffer overflow"); | 467 | err("reg_r: buffer overflow"); |
466 | return; | 468 | return; |
467 | } | 469 | } |
468 | #endif | 470 | #endif |
469 | usb_control_msg(gspca_dev->dev, | 471 | if (gspca_dev->usb_err < 0) |
472 | return; | ||
473 | ret = usb_control_msg(gspca_dev->dev, | ||
470 | usb_rcvctrlpipe(gspca_dev->dev, 0), | 474 | usb_rcvctrlpipe(gspca_dev->dev, 0), |
471 | req, | 475 | req, |
472 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 476 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
@@ -474,6 +478,10 @@ static void reg_r(struct gspca_dev *gspca_dev, | |||
474 | index, | 478 | index, |
475 | len ? gspca_dev->usb_buf : NULL, len, | 479 | len ? gspca_dev->usb_buf : NULL, len, |
476 | 500); | 480 | 500); |
481 | if (ret < 0) { | ||
482 | PDEBUG(D_ERR, "reg_r err %d", ret); | ||
483 | gspca_dev->usb_err = ret; | ||
484 | } | ||
477 | } | 485 | } |
478 | 486 | ||
479 | /* write one byte */ | 487 | /* write one byte */ |
@@ -483,40 +491,55 @@ static void reg_w_1(struct gspca_dev *gspca_dev, | |||
483 | u16 index, | 491 | u16 index, |
484 | u16 byte) | 492 | u16 byte) |
485 | { | 493 | { |
494 | int ret; | ||
495 | |||
496 | if (gspca_dev->usb_err < 0) | ||
497 | return; | ||
486 | gspca_dev->usb_buf[0] = byte; | 498 | gspca_dev->usb_buf[0] = byte; |
487 | usb_control_msg(gspca_dev->dev, | 499 | ret = usb_control_msg(gspca_dev->dev, |
488 | usb_sndctrlpipe(gspca_dev->dev, 0), | 500 | usb_sndctrlpipe(gspca_dev->dev, 0), |
489 | req, | 501 | req, |
490 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 502 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
491 | value, index, | 503 | value, index, |
492 | gspca_dev->usb_buf, 1, | 504 | gspca_dev->usb_buf, 1, |
493 | 500); | 505 | 500); |
506 | if (ret < 0) { | ||
507 | PDEBUG(D_ERR, "reg_w_1 err %d", ret); | ||
508 | gspca_dev->usb_err = ret; | ||
509 | } | ||
494 | } | 510 | } |
495 | 511 | ||
496 | /* write req / index / value */ | 512 | /* write req / index / value */ |
497 | static int reg_w_riv(struct usb_device *dev, | 513 | static void reg_w_riv(struct gspca_dev *gspca_dev, |
498 | u8 req, u16 index, u16 value) | 514 | u8 req, u16 index, u16 value) |
499 | { | 515 | { |
516 | struct usb_device *dev = gspca_dev->dev; | ||
500 | int ret; | 517 | int ret; |
501 | 518 | ||
519 | if (gspca_dev->usb_err < 0) | ||
520 | return; | ||
502 | ret = usb_control_msg(dev, | 521 | ret = usb_control_msg(dev, |
503 | usb_sndctrlpipe(dev, 0), | 522 | usb_sndctrlpipe(dev, 0), |
504 | req, | 523 | req, |
505 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 524 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
506 | value, index, NULL, 0, 500); | 525 | value, index, NULL, 0, 500); |
507 | PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d", | 526 | if (ret < 0) { |
508 | req, index, value, ret); | 527 | PDEBUG(D_ERR, "reg_w_riv err %d", ret); |
509 | if (ret < 0) | 528 | gspca_dev->usb_err = ret; |
510 | PDEBUG(D_ERR, "reg write: error %d", ret); | 529 | return; |
511 | return ret; | 530 | } |
531 | PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x", | ||
532 | req, index, value); | ||
512 | } | 533 | } |
513 | 534 | ||
514 | /* read 1 byte */ | 535 | /* read 1 byte */ |
515 | static int reg_r_1(struct gspca_dev *gspca_dev, | 536 | static u8 reg_r_1(struct gspca_dev *gspca_dev, |
516 | u16 value) /* wValue */ | 537 | u16 value) /* wValue */ |
517 | { | 538 | { |
518 | int ret; | 539 | int ret; |
519 | 540 | ||
541 | if (gspca_dev->usb_err < 0) | ||
542 | return 0; | ||
520 | ret = usb_control_msg(gspca_dev->dev, | 543 | ret = usb_control_msg(gspca_dev->dev, |
521 | usb_rcvctrlpipe(gspca_dev->dev, 0), | 544 | usb_rcvctrlpipe(gspca_dev->dev, 0), |
522 | 0x20, /* request */ | 545 | 0x20, /* request */ |
@@ -527,19 +550,22 @@ static int reg_r_1(struct gspca_dev *gspca_dev, | |||
527 | 500); /* timeout */ | 550 | 500); /* timeout */ |
528 | if (ret < 0) { | 551 | if (ret < 0) { |
529 | PDEBUG(D_ERR, "reg_r_1 err %d", ret); | 552 | PDEBUG(D_ERR, "reg_r_1 err %d", ret); |
553 | gspca_dev->usb_err = ret; | ||
530 | return 0; | 554 | return 0; |
531 | } | 555 | } |
532 | return gspca_dev->usb_buf[0]; | 556 | return gspca_dev->usb_buf[0]; |
533 | } | 557 | } |
534 | 558 | ||
535 | /* read 1 or 2 bytes - returns < 0 if error */ | 559 | /* read 1 or 2 bytes */ |
536 | static int reg_r_12(struct gspca_dev *gspca_dev, | 560 | static u16 reg_r_12(struct gspca_dev *gspca_dev, |
537 | u8 req, /* bRequest */ | 561 | u8 req, /* bRequest */ |
538 | u16 index, /* wIndex */ | 562 | u16 index, /* wIndex */ |
539 | u16 length) /* wLength (1 or 2 only) */ | 563 | u16 length) /* wLength (1 or 2 only) */ |
540 | { | 564 | { |
541 | int ret; | 565 | int ret; |
542 | 566 | ||
567 | if (gspca_dev->usb_err < 0) | ||
568 | return 0; | ||
543 | gspca_dev->usb_buf[1] = 0; | 569 | gspca_dev->usb_buf[1] = 0; |
544 | ret = usb_control_msg(gspca_dev->dev, | 570 | ret = usb_control_msg(gspca_dev->dev, |
545 | usb_rcvctrlpipe(gspca_dev->dev, 0), | 571 | usb_rcvctrlpipe(gspca_dev->dev, 0), |
@@ -550,62 +576,44 @@ static int reg_r_12(struct gspca_dev *gspca_dev, | |||
550 | gspca_dev->usb_buf, length, | 576 | gspca_dev->usb_buf, length, |
551 | 500); | 577 | 500); |
552 | if (ret < 0) { | 578 | if (ret < 0) { |
553 | PDEBUG(D_ERR, "reg_read err %d", ret); | 579 | PDEBUG(D_ERR, "reg_r_12 err %d", ret); |
554 | return -1; | 580 | gspca_dev->usb_err = ret; |
581 | return 0; | ||
555 | } | 582 | } |
556 | return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; | 583 | return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; |
557 | } | 584 | } |
558 | 585 | ||
559 | static int write_vector(struct gspca_dev *gspca_dev, | 586 | static void write_vector(struct gspca_dev *gspca_dev, |
560 | const struct cmd *data, int ncmds) | 587 | const struct cmd *data, int ncmds) |
561 | { | 588 | { |
562 | struct usb_device *dev = gspca_dev->dev; | ||
563 | int ret; | ||
564 | |||
565 | while (--ncmds >= 0) { | 589 | while (--ncmds >= 0) { |
566 | ret = reg_w_riv(dev, data->req, data->idx, data->val); | 590 | reg_w_riv(gspca_dev, data->req, data->idx, data->val); |
567 | if (ret < 0) { | ||
568 | PDEBUG(D_ERR, | ||
569 | "Register write failed for 0x%02x, 0x%04x, 0x%04x", | ||
570 | data->req, data->val, data->idx); | ||
571 | return ret; | ||
572 | } | ||
573 | data++; | 591 | data++; |
574 | } | 592 | } |
575 | return 0; | ||
576 | } | 593 | } |
577 | 594 | ||
578 | static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, | 595 | static void setup_qtable(struct gspca_dev *gspca_dev, |
579 | const u8 qtable[2][64]) | 596 | const u8 qtable[2][64]) |
580 | { | 597 | { |
581 | struct usb_device *dev = gspca_dev->dev; | 598 | int i; |
582 | int i, err; | ||
583 | 599 | ||
584 | /* loop over y components */ | 600 | /* loop over y components */ |
585 | for (i = 0; i < 64; i++) { | 601 | for (i = 0; i < 64; i++) |
586 | err = reg_w_riv(dev, 0x00, 0x2800 + i, qtable[0][i]); | 602 | reg_w_riv(gspca_dev, 0x00, 0x2800 + i, qtable[0][i]); |
587 | if (err < 0) | ||
588 | return err; | ||
589 | } | ||
590 | 603 | ||
591 | /* loop over c components */ | 604 | /* loop over c components */ |
592 | for (i = 0; i < 64; i++) { | 605 | for (i = 0; i < 64; i++) |
593 | err = reg_w_riv(dev, 0x00, 0x2840 + i, qtable[1][i]); | 606 | reg_w_riv(gspca_dev, 0x00, 0x2840 + i, qtable[1][i]); |
594 | if (err < 0) | ||
595 | return err; | ||
596 | } | ||
597 | return 0; | ||
598 | } | 607 | } |
599 | 608 | ||
600 | static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, | 609 | static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, |
601 | u8 req, u16 idx, u16 val) | 610 | u8 req, u16 idx, u16 val) |
602 | { | 611 | { |
603 | struct usb_device *dev = gspca_dev->dev; | 612 | u16 notdone; |
604 | int notdone; | ||
605 | 613 | ||
606 | reg_w_riv(dev, req, idx, val); | 614 | reg_w_riv(gspca_dev, req, idx, val); |
607 | notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); | 615 | notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); |
608 | reg_w_riv(dev, req, idx, val); | 616 | reg_w_riv(gspca_dev, req, idx, val); |
609 | 617 | ||
610 | PDEBUG(D_FRAM, "before wait 0x%04x", notdone); | 618 | PDEBUG(D_FRAM, "before wait 0x%04x", notdone); |
611 | 619 | ||
@@ -616,23 +624,22 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, | |||
616 | 624 | ||
617 | static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, | 625 | static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, |
618 | u8 req, | 626 | u8 req, |
619 | u16 idx, u16 val, u8 stat, u8 count) | 627 | u16 idx, u16 val, u16 endcode, u8 count) |
620 | { | 628 | { |
621 | struct usb_device *dev = gspca_dev->dev; | 629 | u16 status; |
622 | int status; | ||
623 | u8 endcode; | ||
624 | 630 | ||
625 | reg_w_riv(dev, req, idx, val); | 631 | reg_w_riv(gspca_dev, req, idx, val); |
626 | status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); | 632 | status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); |
627 | endcode = stat; | 633 | if (gspca_dev->usb_err < 0) |
628 | PDEBUG(D_FRAM, "Status 0x%x Need 0x%04x", status, stat); | 634 | return; |
635 | PDEBUG(D_FRAM, "Status 0x%04x Need 0x%04x", status, endcode); | ||
629 | if (!count) | 636 | if (!count) |
630 | return; | 637 | return; |
631 | count = 200; | 638 | count = 200; |
632 | while (--count > 0) { | 639 | while (--count > 0) { |
633 | msleep(10); | 640 | msleep(10); |
634 | /* gsmart mini2 write a each wait setting 1 ms is enough */ | 641 | /* gsmart mini2 write a each wait setting 1 ms is enough */ |
635 | /* reg_w_riv(dev, req, idx, val); */ | 642 | /* reg_w_riv(gspca_dev, req, idx, val); */ |
636 | status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); | 643 | status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); |
637 | if (status == endcode) { | 644 | if (status == endcode) { |
638 | PDEBUG(D_FRAM, "status 0x%04x after wait %d", | 645 | PDEBUG(D_FRAM, "status 0x%04x after wait %d", |
@@ -642,7 +649,7 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, | |||
642 | } | 649 | } |
643 | } | 650 | } |
644 | 651 | ||
645 | static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev) | 652 | static void spca504B_PollingDataReady(struct gspca_dev *gspca_dev) |
646 | { | 653 | { |
647 | int count = 10; | 654 | int count = 10; |
648 | 655 | ||
@@ -652,7 +659,6 @@ static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev) | |||
652 | break; | 659 | break; |
653 | msleep(10); | 660 | msleep(10); |
654 | } | 661 | } |
655 | return gspca_dev->usb_buf[0]; | ||
656 | } | 662 | } |
657 | 663 | ||
658 | static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) | 664 | static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) |
@@ -686,28 +692,26 @@ static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) | |||
686 | static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) | 692 | static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) |
687 | { | 693 | { |
688 | struct sd *sd = (struct sd *) gspca_dev; | 694 | struct sd *sd = (struct sd *) gspca_dev; |
689 | struct usb_device *dev = gspca_dev->dev; | ||
690 | u8 Size; | 695 | u8 Size; |
691 | int rc; | ||
692 | 696 | ||
693 | Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | 697 | Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
694 | switch (sd->bridge) { | 698 | switch (sd->bridge) { |
695 | case BRIDGE_SPCA533: | 699 | case BRIDGE_SPCA533: |
696 | reg_w_riv(dev, 0x31, 0, 0); | 700 | reg_w_riv(gspca_dev, 0x31, 0, 0); |
697 | spca504B_WaitCmdStatus(gspca_dev); | 701 | spca504B_WaitCmdStatus(gspca_dev); |
698 | rc = spca504B_PollingDataReady(gspca_dev); | 702 | spca504B_PollingDataReady(gspca_dev); |
699 | spca50x_GetFirmware(gspca_dev); | 703 | spca50x_GetFirmware(gspca_dev); |
700 | reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */ | 704 | reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */ |
701 | reg_r(gspca_dev, 0x24, 8, 1); | 705 | reg_r(gspca_dev, 0x24, 8, 1); |
702 | 706 | ||
703 | reg_w_1(gspca_dev, 0x25, 0, 4, Size); | 707 | reg_w_1(gspca_dev, 0x25, 0, 4, Size); |
704 | reg_r(gspca_dev, 0x25, 4, 1); /* size */ | 708 | reg_r(gspca_dev, 0x25, 4, 1); /* size */ |
705 | rc = spca504B_PollingDataReady(gspca_dev); | 709 | spca504B_PollingDataReady(gspca_dev); |
706 | 710 | ||
707 | /* Init the cam width height with some values get on init ? */ | 711 | /* Init the cam width height with some values get on init ? */ |
708 | reg_w_riv(dev, 0x31, 0, 0x04); | 712 | reg_w_riv(gspca_dev, 0x31, 0, 0x04); |
709 | spca504B_WaitCmdStatus(gspca_dev); | 713 | spca504B_WaitCmdStatus(gspca_dev); |
710 | rc = spca504B_PollingDataReady(gspca_dev); | 714 | spca504B_PollingDataReady(gspca_dev); |
711 | break; | 715 | break; |
712 | default: | 716 | default: |
713 | /* case BRIDGE_SPCA504B: */ | 717 | /* case BRIDGE_SPCA504B: */ |
@@ -716,7 +720,7 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) | |||
716 | reg_r(gspca_dev, 0x25, 4, 1); /* size */ | 720 | reg_r(gspca_dev, 0x25, 4, 1); /* size */ |
717 | reg_w_1(gspca_dev, 0x27, 0, 0, 6); | 721 | reg_w_1(gspca_dev, 0x27, 0, 0, 6); |
718 | reg_r(gspca_dev, 0x27, 0, 1); /* type */ | 722 | reg_r(gspca_dev, 0x27, 0, 1); /* type */ |
719 | rc = spca504B_PollingDataReady(gspca_dev); | 723 | spca504B_PollingDataReady(gspca_dev); |
720 | break; | 724 | break; |
721 | case BRIDGE_SPCA504: | 725 | case BRIDGE_SPCA504: |
722 | Size += 3; | 726 | Size += 3; |
@@ -733,8 +737,8 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) | |||
733 | break; | 737 | break; |
734 | case BRIDGE_SPCA504C: | 738 | case BRIDGE_SPCA504C: |
735 | /* capture mode */ | 739 | /* capture mode */ |
736 | reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00); | 740 | reg_w_riv(gspca_dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00); |
737 | reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); | 741 | reg_w_riv(gspca_dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); |
738 | break; | 742 | break; |
739 | } | 743 | } |
740 | } | 744 | } |
@@ -762,37 +766,33 @@ static void spca504B_setQtable(struct gspca_dev *gspca_dev) | |||
762 | static void setbrightness(struct gspca_dev *gspca_dev) | 766 | static void setbrightness(struct gspca_dev *gspca_dev) |
763 | { | 767 | { |
764 | struct sd *sd = (struct sd *) gspca_dev; | 768 | struct sd *sd = (struct sd *) gspca_dev; |
765 | struct usb_device *dev = gspca_dev->dev; | ||
766 | u16 reg; | 769 | u16 reg; |
767 | 770 | ||
768 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7; | 771 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7; |
769 | reg_w_riv(dev, 0x00, reg, sd->brightness); | 772 | reg_w_riv(gspca_dev, 0x00, reg, sd->brightness); |
770 | } | 773 | } |
771 | 774 | ||
772 | static void setcontrast(struct gspca_dev *gspca_dev) | 775 | static void setcontrast(struct gspca_dev *gspca_dev) |
773 | { | 776 | { |
774 | struct sd *sd = (struct sd *) gspca_dev; | 777 | struct sd *sd = (struct sd *) gspca_dev; |
775 | struct usb_device *dev = gspca_dev->dev; | ||
776 | u16 reg; | 778 | u16 reg; |
777 | 779 | ||
778 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8; | 780 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8; |
779 | reg_w_riv(dev, 0x00, reg, sd->contrast); | 781 | reg_w_riv(gspca_dev, 0x00, reg, sd->contrast); |
780 | } | 782 | } |
781 | 783 | ||
782 | static void setcolors(struct gspca_dev *gspca_dev) | 784 | static void setcolors(struct gspca_dev *gspca_dev) |
783 | { | 785 | { |
784 | struct sd *sd = (struct sd *) gspca_dev; | 786 | struct sd *sd = (struct sd *) gspca_dev; |
785 | struct usb_device *dev = gspca_dev->dev; | ||
786 | u16 reg; | 787 | u16 reg; |
787 | 788 | ||
788 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae; | 789 | reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae; |
789 | reg_w_riv(dev, 0x00, reg, sd->colors); | 790 | reg_w_riv(gspca_dev, 0x00, reg, sd->colors); |
790 | } | 791 | } |
791 | 792 | ||
792 | static void init_ctl_reg(struct gspca_dev *gspca_dev) | 793 | static void init_ctl_reg(struct gspca_dev *gspca_dev) |
793 | { | 794 | { |
794 | struct sd *sd = (struct sd *) gspca_dev; | 795 | struct sd *sd = (struct sd *) gspca_dev; |
795 | struct usb_device *dev = gspca_dev->dev; | ||
796 | int pollreg = 1; | 796 | int pollreg = 1; |
797 | 797 | ||
798 | setbrightness(gspca_dev); | 798 | setbrightness(gspca_dev); |
@@ -807,14 +807,14 @@ static void init_ctl_reg(struct gspca_dev *gspca_dev) | |||
807 | default: | 807 | default: |
808 | /* case BRIDGE_SPCA533: */ | 808 | /* case BRIDGE_SPCA533: */ |
809 | /* case BRIDGE_SPCA504B: */ | 809 | /* case BRIDGE_SPCA504B: */ |
810 | reg_w_riv(dev, 0, 0x00, 0x21ad); /* hue */ | 810 | reg_w_riv(gspca_dev, 0, 0x00, 0x21ad); /* hue */ |
811 | reg_w_riv(dev, 0, 0x01, 0x21ac); /* sat/hue */ | 811 | reg_w_riv(gspca_dev, 0, 0x01, 0x21ac); /* sat/hue */ |
812 | reg_w_riv(dev, 0, 0x00, 0x21a3); /* gamma */ | 812 | reg_w_riv(gspca_dev, 0, 0x00, 0x21a3); /* gamma */ |
813 | break; | 813 | break; |
814 | case BRIDGE_SPCA536: | 814 | case BRIDGE_SPCA536: |
815 | reg_w_riv(dev, 0, 0x40, 0x20f5); | 815 | reg_w_riv(gspca_dev, 0, 0x40, 0x20f5); |
816 | reg_w_riv(dev, 0, 0x01, 0x20f4); | 816 | reg_w_riv(gspca_dev, 0, 0x01, 0x20f4); |
817 | reg_w_riv(dev, 0, 0x00, 0x2089); | 817 | reg_w_riv(gspca_dev, 0, 0x00, 0x2089); |
818 | break; | 818 | break; |
819 | } | 819 | } |
820 | if (pollreg) | 820 | if (pollreg) |
@@ -881,18 +881,17 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
881 | static int sd_init(struct gspca_dev *gspca_dev) | 881 | static int sd_init(struct gspca_dev *gspca_dev) |
882 | { | 882 | { |
883 | struct sd *sd = (struct sd *) gspca_dev; | 883 | struct sd *sd = (struct sd *) gspca_dev; |
884 | struct usb_device *dev = gspca_dev->dev; | 884 | int i; |
885 | int i, err_code; | ||
886 | u8 info[6]; | 885 | u8 info[6]; |
887 | 886 | ||
888 | switch (sd->bridge) { | 887 | switch (sd->bridge) { |
889 | case BRIDGE_SPCA504B: | 888 | case BRIDGE_SPCA504B: |
890 | reg_w_riv(dev, 0x1d, 0x00, 0); | 889 | reg_w_riv(gspca_dev, 0x1d, 0x00, 0); |
891 | reg_w_riv(dev, 0, 0x01, 0x2306); | 890 | reg_w_riv(gspca_dev, 0, 0x01, 0x2306); |
892 | reg_w_riv(dev, 0, 0x00, 0x0d04); | 891 | reg_w_riv(gspca_dev, 0, 0x00, 0x0d04); |
893 | reg_w_riv(dev, 0, 0x00, 0x2000); | 892 | reg_w_riv(gspca_dev, 0, 0x00, 0x2000); |
894 | reg_w_riv(dev, 0, 0x13, 0x2301); | 893 | reg_w_riv(gspca_dev, 0, 0x13, 0x2301); |
895 | reg_w_riv(dev, 0, 0x00, 0x2306); | 894 | reg_w_riv(gspca_dev, 0, 0x00, 0x2306); |
896 | /* fall thru */ | 895 | /* fall thru */ |
897 | case BRIDGE_SPCA533: | 896 | case BRIDGE_SPCA533: |
898 | spca504B_PollingDataReady(gspca_dev); | 897 | spca504B_PollingDataReady(gspca_dev); |
@@ -904,13 +903,13 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
904 | reg_w_1(gspca_dev, 0x24, 0, 0, 0); | 903 | reg_w_1(gspca_dev, 0x24, 0, 0, 0); |
905 | reg_r(gspca_dev, 0x24, 0, 1); | 904 | reg_r(gspca_dev, 0x24, 0, 1); |
906 | spca504B_PollingDataReady(gspca_dev); | 905 | spca504B_PollingDataReady(gspca_dev); |
907 | reg_w_riv(dev, 0x34, 0, 0); | 906 | reg_w_riv(gspca_dev, 0x34, 0, 0); |
908 | spca504B_WaitCmdStatus(gspca_dev); | 907 | spca504B_WaitCmdStatus(gspca_dev); |
909 | break; | 908 | break; |
910 | case BRIDGE_SPCA504C: /* pccam600 */ | 909 | case BRIDGE_SPCA504C: /* pccam600 */ |
911 | PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)"); | 910 | PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)"); |
912 | reg_w_riv(dev, 0xe0, 0x0000, 0x0000); | 911 | reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000); |
913 | reg_w_riv(dev, 0xe0, 0x0000, 0x0001); /* reset */ | 912 | reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001); /* reset */ |
914 | spca504_wait_status(gspca_dev); | 913 | spca504_wait_status(gspca_dev); |
915 | if (sd->subtype == LogitechClickSmart420) | 914 | if (sd->subtype == LogitechClickSmart420) |
916 | write_vector(gspca_dev, | 915 | write_vector(gspca_dev, |
@@ -919,12 +918,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
919 | else | 918 | else |
920 | write_vector(gspca_dev, spca504_pccam600_open_data, | 919 | write_vector(gspca_dev, spca504_pccam600_open_data, |
921 | ARRAY_SIZE(spca504_pccam600_open_data)); | 920 | ARRAY_SIZE(spca504_pccam600_open_data)); |
922 | err_code = spca50x_setup_qtable(gspca_dev, | 921 | setup_qtable(gspca_dev, qtable_creative_pccam); |
923 | qtable_creative_pccam); | ||
924 | if (err_code < 0) { | ||
925 | PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed"); | ||
926 | return err_code; | ||
927 | } | ||
928 | break; | 922 | break; |
929 | default: | 923 | default: |
930 | /* case BRIDGE_SPCA504: */ | 924 | /* case BRIDGE_SPCA504: */ |
@@ -958,29 +952,24 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
958 | 6, 0, 0x86, 1); */ | 952 | 6, 0, 0x86, 1); */ |
959 | /* spca504A_acknowledged_command (gspca_dev, 0x24, | 953 | /* spca504A_acknowledged_command (gspca_dev, 0x24, |
960 | 0, 0, 0x9D, 1); */ | 954 | 0, 0, 0x9D, 1); */ |
961 | reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */ | 955 | reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05); |
962 | reg_w_riv(dev, 0x00, 0x2310, 0x05); | 956 | /* L92 sno1t.txt */ |
957 | reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05); | ||
963 | spca504A_acknowledged_command(gspca_dev, 0x01, | 958 | spca504A_acknowledged_command(gspca_dev, 0x01, |
964 | 0x0f, 0, 0xff, 0); | 959 | 0x0f, 0, 0xff, 0); |
965 | } | 960 | } |
966 | /* setup qtable */ | 961 | /* setup qtable */ |
967 | reg_w_riv(dev, 0, 0x2000, 0); | 962 | reg_w_riv(gspca_dev, 0, 0x2000, 0); |
968 | reg_w_riv(dev, 0, 0x2883, 1); | 963 | reg_w_riv(gspca_dev, 0, 0x2883, 1); |
969 | err_code = spca50x_setup_qtable(gspca_dev, | 964 | setup_qtable(gspca_dev, qtable_spca504_default); |
970 | qtable_spca504_default); | ||
971 | if (err_code < 0) { | ||
972 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
973 | return err_code; | ||
974 | } | ||
975 | break; | 965 | break; |
976 | } | 966 | } |
977 | return 0; | 967 | return gspca_dev->usb_err; |
978 | } | 968 | } |
979 | 969 | ||
980 | static int sd_start(struct gspca_dev *gspca_dev) | 970 | static int sd_start(struct gspca_dev *gspca_dev) |
981 | { | 971 | { |
982 | struct sd *sd = (struct sd *) gspca_dev; | 972 | struct sd *sd = (struct sd *) gspca_dev; |
983 | struct usb_device *dev = gspca_dev->dev; | ||
984 | int enable; | 973 | int enable; |
985 | int i; | 974 | int i; |
986 | u8 info[6]; | 975 | u8 info[6]; |
@@ -1005,13 +994,13 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1005 | case MegapixV4: | 994 | case MegapixV4: |
1006 | case LogitechClickSmart820: | 995 | case LogitechClickSmart820: |
1007 | case MegaImageVI: | 996 | case MegaImageVI: |
1008 | reg_w_riv(dev, 0xf0, 0, 0); | 997 | reg_w_riv(gspca_dev, 0xf0, 0, 0); |
1009 | spca504B_WaitCmdStatus(gspca_dev); | 998 | spca504B_WaitCmdStatus(gspca_dev); |
1010 | reg_r(gspca_dev, 0xf0, 4, 0); | 999 | reg_r(gspca_dev, 0xf0, 4, 0); |
1011 | spca504B_WaitCmdStatus(gspca_dev); | 1000 | spca504B_WaitCmdStatus(gspca_dev); |
1012 | break; | 1001 | break; |
1013 | default: | 1002 | default: |
1014 | reg_w_riv(dev, 0x31, 0, 0x04); | 1003 | reg_w_riv(gspca_dev, 0x31, 0, 0x04); |
1015 | spca504B_WaitCmdStatus(gspca_dev); | 1004 | spca504B_WaitCmdStatus(gspca_dev); |
1016 | spca504B_PollingDataReady(gspca_dev); | 1005 | spca504B_PollingDataReady(gspca_dev); |
1017 | break; | 1006 | break; |
@@ -1048,8 +1037,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1048 | spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); | 1037 | spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); |
1049 | } | 1038 | } |
1050 | spca504B_SetSizeType(gspca_dev); | 1039 | spca504B_SetSizeType(gspca_dev); |
1051 | reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */ | 1040 | reg_w_riv(gspca_dev, 0x00, 0x270c, 0x05); |
1052 | reg_w_riv(dev, 0x00, 0x2310, 0x05); | 1041 | /* L92 sno1t.txt */ |
1042 | reg_w_riv(gspca_dev, 0x00, 0x2310, 0x05); | ||
1053 | break; | 1043 | break; |
1054 | case BRIDGE_SPCA504C: | 1044 | case BRIDGE_SPCA504C: |
1055 | if (sd->subtype == LogitechClickSmart420) { | 1045 | if (sd->subtype == LogitechClickSmart420) { |
@@ -1061,36 +1051,37 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
1061 | ARRAY_SIZE(spca504_pccam600_init_data)); | 1051 | ARRAY_SIZE(spca504_pccam600_init_data)); |
1062 | } | 1052 | } |
1063 | enable = (sd->autogain ? 0x04 : 0x01); | 1053 | enable = (sd->autogain ? 0x04 : 0x01); |
1064 | reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */ | 1054 | reg_w_riv(gspca_dev, 0x0c, 0x0000, enable); |
1065 | reg_w_riv(dev, 0xb0, 0x0000, enable); /* auto whiteness */ | 1055 | /* auto exposure */ |
1056 | reg_w_riv(gspca_dev, 0xb0, 0x0000, enable); | ||
1057 | /* auto whiteness */ | ||
1066 | 1058 | ||
1067 | /* set default exposure compensation and whiteness balance */ | 1059 | /* set default exposure compensation and whiteness balance */ |
1068 | reg_w_riv(dev, 0x30, 0x0001, 800); /* ~ 20 fps */ | 1060 | reg_w_riv(gspca_dev, 0x30, 0x0001, 800); /* ~ 20 fps */ |
1069 | reg_w_riv(dev, 0x30, 0x0002, 1600); | 1061 | reg_w_riv(gspca_dev, 0x30, 0x0002, 1600); |
1070 | spca504B_SetSizeType(gspca_dev); | 1062 | spca504B_SetSizeType(gspca_dev); |
1071 | break; | 1063 | break; |
1072 | } | 1064 | } |
1073 | init_ctl_reg(gspca_dev); | 1065 | init_ctl_reg(gspca_dev); |
1074 | return 0; | 1066 | return gspca_dev->usb_err; |
1075 | } | 1067 | } |
1076 | 1068 | ||
1077 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1069 | static void sd_stopN(struct gspca_dev *gspca_dev) |
1078 | { | 1070 | { |
1079 | struct sd *sd = (struct sd *) gspca_dev; | 1071 | struct sd *sd = (struct sd *) gspca_dev; |
1080 | struct usb_device *dev = gspca_dev->dev; | ||
1081 | 1072 | ||
1082 | switch (sd->bridge) { | 1073 | switch (sd->bridge) { |
1083 | default: | 1074 | default: |
1084 | /* case BRIDGE_SPCA533: */ | 1075 | /* case BRIDGE_SPCA533: */ |
1085 | /* case BRIDGE_SPCA536: */ | 1076 | /* case BRIDGE_SPCA536: */ |
1086 | /* case BRIDGE_SPCA504B: */ | 1077 | /* case BRIDGE_SPCA504B: */ |
1087 | reg_w_riv(dev, 0x31, 0, 0); | 1078 | reg_w_riv(gspca_dev, 0x31, 0, 0); |
1088 | spca504B_WaitCmdStatus(gspca_dev); | 1079 | spca504B_WaitCmdStatus(gspca_dev); |
1089 | spca504B_PollingDataReady(gspca_dev); | 1080 | spca504B_PollingDataReady(gspca_dev); |
1090 | break; | 1081 | break; |
1091 | case BRIDGE_SPCA504: | 1082 | case BRIDGE_SPCA504: |
1092 | case BRIDGE_SPCA504C: | 1083 | case BRIDGE_SPCA504C: |
1093 | reg_w_riv(dev, 0x00, 0x2000, 0x0000); | 1084 | reg_w_riv(gspca_dev, 0x00, 0x2000, 0x0000); |
1094 | 1085 | ||
1095 | if (sd->subtype == AiptekMiniPenCam13) { | 1086 | if (sd->subtype == AiptekMiniPenCam13) { |
1096 | /* spca504a aiptek */ | 1087 | /* spca504a aiptek */ |
@@ -1102,7 +1093,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
1102 | 0x0f, 0x00, 0xff, 1); | 1093 | 0x0f, 0x00, 0xff, 1); |
1103 | } else { | 1094 | } else { |
1104 | spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); | 1095 | spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); |
1105 | reg_w_riv(dev, 0x01, 0x000f, 0x0000); | 1096 | reg_w_riv(gspca_dev, 0x01, 0x000f, 0x0000); |
1106 | } | 1097 | } |
1107 | break; | 1098 | break; |
1108 | } | 1099 | } |
@@ -1216,7 +1207,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | |||
1216 | sd->brightness = val; | 1207 | sd->brightness = val; |
1217 | if (gspca_dev->streaming) | 1208 | if (gspca_dev->streaming) |
1218 | setbrightness(gspca_dev); | 1209 | setbrightness(gspca_dev); |
1219 | return 0; | 1210 | return gspca_dev->usb_err; |
1220 | } | 1211 | } |
1221 | 1212 | ||
1222 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | 1213 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -1234,7 +1225,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | |||
1234 | sd->contrast = val; | 1225 | sd->contrast = val; |
1235 | if (gspca_dev->streaming) | 1226 | if (gspca_dev->streaming) |
1236 | setcontrast(gspca_dev); | 1227 | setcontrast(gspca_dev); |
1237 | return 0; | 1228 | return gspca_dev->usb_err; |
1238 | } | 1229 | } |
1239 | 1230 | ||
1240 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | 1231 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -1252,7 +1243,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | |||
1252 | sd->colors = val; | 1243 | sd->colors = val; |
1253 | if (gspca_dev->streaming) | 1244 | if (gspca_dev->streaming) |
1254 | setcolors(gspca_dev); | 1245 | setcolors(gspca_dev); |
1255 | return 0; | 1246 | return gspca_dev->usb_err; |
1256 | } | 1247 | } |
1257 | 1248 | ||
1258 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | 1249 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) |
@@ -1292,7 +1283,7 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, | |||
1292 | sd->quality = jcomp->quality; | 1283 | sd->quality = jcomp->quality; |
1293 | if (gspca_dev->streaming) | 1284 | if (gspca_dev->streaming) |
1294 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 1285 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); |
1295 | return 0; | 1286 | return gspca_dev->usb_err; |
1296 | } | 1287 | } |
1297 | 1288 | ||
1298 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 1289 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 69e5dc4fc9d..1a800fc1c00 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -5345,9 +5345,6 @@ static const struct usb_action tas5130cxx_InitialScale[] = { /* 320x240 */ | |||
5345 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | 5345 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, |
5346 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | 5346 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, |
5347 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | 5347 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, |
5348 | {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, | ||
5349 | {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, | ||
5350 | |||
5351 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | 5348 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, |
5352 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | 5349 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, |
5353 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | 5350 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, |
@@ -5364,27 +5361,27 @@ static const struct usb_action tas5130cxx_InitialScale[] = { /* 320x240 */ | |||
5364 | {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, | 5361 | {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, |
5365 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | 5362 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, |
5366 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | 5363 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, |
5367 | {0xa0, 0x95, ZC3XX_R18D_YTARGET}, | 5364 | {0xa0, 0x70, ZC3XX_R18D_YTARGET}, |
5368 | {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, | 5365 | {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, |
5369 | {0xa0, 0x00, 0x01ad}, | 5366 | {0xa0, 0x00, 0x01ad}, |
5370 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | 5367 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, |
5371 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | 5368 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, |
5372 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | 5369 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, |
5373 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | 5370 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, |
5371 | {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, | ||
5372 | {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, | ||
5374 | {} | 5373 | {} |
5375 | }; | 5374 | }; |
5376 | static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */ | 5375 | static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */ |
5377 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | 5376 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, |
5378 | {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, | 5377 | {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, |
5379 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | 5378 | {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, |
5380 | {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, | 5379 | {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, |
5381 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | 5380 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, |
5382 | {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, | 5381 | {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, |
5383 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | 5382 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, |
5384 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | 5383 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, |
5385 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | 5384 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, |
5386 | {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, | ||
5387 | {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, | ||
5388 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | 5385 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, |
5389 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | 5386 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, |
5390 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | 5387 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, |
@@ -5400,13 +5397,15 @@ static const struct usb_action tas5130cxx_Initial[] = { /* 640x480 */ | |||
5400 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | 5397 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, |
5401 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | 5398 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, |
5402 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | 5399 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, |
5403 | {0xa0, 0x95, ZC3XX_R18D_YTARGET}, | 5400 | {0xa0, 0x70, ZC3XX_R18D_YTARGET}, |
5404 | {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, | 5401 | {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, |
5405 | {0xa0, 0x00, 0x01ad}, | 5402 | {0xa0, 0x00, 0x01ad}, |
5406 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | 5403 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, |
5407 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | 5404 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, |
5408 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | 5405 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, |
5409 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | 5406 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, |
5407 | {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, | ||
5408 | {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, | ||
5410 | {} | 5409 | {} |
5411 | }; | 5410 | }; |
5412 | static const struct usb_action tas5130cxx_50HZ[] = { | 5411 | static const struct usb_action tas5130cxx_50HZ[] = { |
@@ -6424,11 +6423,11 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev) | |||
6424 | if (retword != 0) | 6423 | if (retword != 0) |
6425 | return 0x0e; /* PAS202BCB */ | 6424 | return 0x0e; /* PAS202BCB */ |
6426 | 6425 | ||
6427 | start_2wr_probe(dev, 0x02); /* ?? */ | 6426 | start_2wr_probe(dev, 0x02); /* TAS5130C */ |
6428 | i2c_write(gspca_dev, 0x01, 0xaa, 0x00); | 6427 | i2c_write(gspca_dev, 0x01, 0xaa, 0x00); |
6429 | retword = i2c_read(gspca_dev, 0x01); | 6428 | retword = i2c_read(gspca_dev, 0x01); |
6430 | if (retword != 0) | 6429 | if (retword != 0) |
6431 | return 0x02; /* ?? */ | 6430 | return 0x02; /* TAS5130C */ |
6432 | ov_check: | 6431 | ov_check: |
6433 | reg_r(gspca_dev, 0x0010); /* ?? */ | 6432 | reg_r(gspca_dev, 0x0010); /* ?? */ |
6434 | reg_r(gspca_dev, 0x0010); | 6433 | reg_r(gspca_dev, 0x0010); |
@@ -6505,6 +6504,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6505 | reg_r(gspca_dev, 0x0010); | 6504 | reg_r(gspca_dev, 0x0010); |
6506 | /* value 0x4001 is meaningless */ | 6505 | /* value 0x4001 is meaningless */ |
6507 | if (retword != 0x4001) { | 6506 | if (retword != 0x4001) { |
6507 | if ((retword & 0xff00) == 0x6400) | ||
6508 | return 0x02; /* TAS5130C */ | ||
6508 | for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { | 6509 | for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { |
6509 | if (chipset_revision_sensor[i].revision == retword) { | 6510 | if (chipset_revision_sensor[i].revision == retword) { |
6510 | sd->chip_revision = retword; | 6511 | sd->chip_revision = retword; |
@@ -6515,7 +6516,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6515 | } | 6516 | } |
6516 | } | 6517 | } |
6517 | 6518 | ||
6518 | reg_w(dev, 0x01, 0x0000); /* check ?? */ | 6519 | reg_w(dev, 0x01, 0x0000); /* check PB0330 */ |
6519 | reg_w(dev, 0x01, 0x0001); | 6520 | reg_w(dev, 0x01, 0x0001); |
6520 | reg_w(dev, 0xdd, 0x008b); | 6521 | reg_w(dev, 0xdd, 0x008b); |
6521 | reg_w(dev, 0x0a, 0x0010); | 6522 | reg_w(dev, 0x0a, 0x0010); |
@@ -6524,7 +6525,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) | |||
6524 | retword = i2c_read(gspca_dev, 0x00); | 6525 | retword = i2c_read(gspca_dev, 0x00); |
6525 | if (retword != 0) { | 6526 | if (retword != 0) { |
6526 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); | 6527 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); |
6527 | return 0x0a; /* ?? */ | 6528 | return 0x0a; /* PB0330 */ |
6528 | } | 6529 | } |
6529 | 6530 | ||
6530 | reg_w(dev, 0x01, 0x0000); | 6531 | reg_w(dev, 0x01, 0x0000); |
@@ -6673,6 +6674,10 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
6673 | PDEBUG(D_PROBE, "Find Sensor HV7131B"); | 6674 | PDEBUG(D_PROBE, "Find Sensor HV7131B"); |
6674 | sd->sensor = SENSOR_HV7131B; | 6675 | sd->sensor = SENSOR_HV7131B; |
6675 | break; | 6676 | break; |
6677 | case 0x02: | ||
6678 | PDEBUG(D_PROBE, "Sensor TAS5130C"); | ||
6679 | sd->sensor = SENSOR_TAS5130CXX; | ||
6680 | break; | ||
6676 | case 0x04: | 6681 | case 0x04: |
6677 | PDEBUG(D_PROBE, "Find Sensor CS2102"); | 6682 | PDEBUG(D_PROBE, "Find Sensor CS2102"); |
6678 | sd->sensor = SENSOR_CS2102; | 6683 | sd->sensor = SENSOR_CS2102; |
@@ -6866,11 +6871,14 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6866 | case SENSOR_GC0305: | 6871 | case SENSOR_GC0305: |
6867 | case SENSOR_OV7620: | 6872 | case SENSOR_OV7620: |
6868 | case SENSOR_PO2030: | 6873 | case SENSOR_PO2030: |
6874 | case SENSOR_TAS5130CXX: | ||
6869 | case SENSOR_TAS5130C_VF0250: | 6875 | case SENSOR_TAS5130C_VF0250: |
6870 | /* msleep(100); * ?? */ | 6876 | /* msleep(100); * ?? */ |
6871 | reg_r(gspca_dev, 0x0002); /* --> 0x40 */ | 6877 | reg_r(gspca_dev, 0x0002); /* --> 0x40 */ |
6872 | reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ | 6878 | reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ |
6873 | reg_w(dev, 0x15, 0x01ae); | 6879 | reg_w(dev, 0x15, 0x01ae); |
6880 | if (sd->sensor == SENSOR_TAS5130CXX) | ||
6881 | break; | ||
6874 | reg_w(dev, 0x0d, 0x003a); | 6882 | reg_w(dev, 0x0d, 0x003a); |
6875 | reg_w(dev, 0x02, 0x003b); | 6883 | reg_w(dev, 0x02, 0x003b); |
6876 | reg_w(dev, 0x00, 0x0038); | 6884 | reg_w(dev, 0x00, 0x0038); |
@@ -6887,6 +6895,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6887 | break; | 6895 | break; |
6888 | case SENSOR_PAS202B: | 6896 | case SENSOR_PAS202B: |
6889 | case SENSOR_GC0305: | 6897 | case SENSOR_GC0305: |
6898 | case SENSOR_TAS5130CXX: | ||
6890 | reg_r(gspca_dev, 0x0008); | 6899 | reg_r(gspca_dev, 0x0008); |
6891 | /* fall thru */ | 6900 | /* fall thru */ |
6892 | case SENSOR_PO2030: | 6901 | case SENSOR_PO2030: |
@@ -6928,6 +6937,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
6928 | reg_w(dev, 0x40, 0x0117); | 6937 | reg_w(dev, 0x40, 0x0117); |
6929 | break; | 6938 | break; |
6930 | case SENSOR_GC0305: | 6939 | case SENSOR_GC0305: |
6940 | case SENSOR_TAS5130CXX: | ||
6931 | reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ | 6941 | reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ |
6932 | reg_w(dev, 0x15, 0x01ae); | 6942 | reg_w(dev, 0x15, 0x01ae); |
6933 | /* fall thru */ | 6943 | /* fall thru */ |
@@ -7220,7 +7230,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
7220 | {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106}, | 7230 | {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106}, |
7221 | {USB_DEVICE(0x0ac8, 0x301b)}, | 7231 | {USB_DEVICE(0x0ac8, 0x301b)}, |
7222 | {USB_DEVICE(0x0ac8, 0x303b)}, | 7232 | {USB_DEVICE(0x0ac8, 0x303b)}, |
7223 | {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, | 7233 | {USB_DEVICE(0x0ac8, 0x305b)}, |
7224 | {USB_DEVICE(0x0ac8, 0x307b)}, | 7234 | {USB_DEVICE(0x0ac8, 0x307b)}, |
7225 | {USB_DEVICE(0x10fd, 0x0128)}, | 7235 | {USB_DEVICE(0x10fd, 0x0128)}, |
7226 | {USB_DEVICE(0x10fd, 0x804d)}, | 7236 | {USB_DEVICE(0x10fd, 0x804d)}, |
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c index 1c9bc94c905..51f393d03a4 100644 --- a/drivers/media/video/hdpvr/hdpvr-core.c +++ b/drivers/media/video/hdpvr/hdpvr-core.c | |||
@@ -145,7 +145,7 @@ static int device_authorization(struct hdpvr_device *dev) | |||
145 | #ifdef HDPVR_DEBUG | 145 | #ifdef HDPVR_DEBUG |
146 | else { | 146 | else { |
147 | hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf, | 147 | hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf, |
148 | sizeof(print_buf), 0); | 148 | 5*buf_size+1, 0); |
149 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, | 149 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, |
150 | "Status request returned, len %d: %s\n", | 150 | "Status request returned, len %d: %s\n", |
151 | ret, print_buf); | 151 | ret, print_buf); |
@@ -168,13 +168,13 @@ static int device_authorization(struct hdpvr_device *dev) | |||
168 | 168 | ||
169 | response = dev->usbc_buf+38; | 169 | response = dev->usbc_buf+38; |
170 | #ifdef HDPVR_DEBUG | 170 | #ifdef HDPVR_DEBUG |
171 | hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0); | 171 | hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); |
172 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n", | 172 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n", |
173 | print_buf); | 173 | print_buf); |
174 | #endif | 174 | #endif |
175 | challenge(response); | 175 | challenge(response); |
176 | #ifdef HDPVR_DEBUG | 176 | #ifdef HDPVR_DEBUG |
177 | hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0); | 177 | hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); |
178 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", | 178 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", |
179 | print_buf); | 179 | print_buf); |
180 | #endif | 180 | #endif |
@@ -376,8 +376,8 @@ static int hdpvr_probe(struct usb_interface *interface, | |||
376 | usb_set_intfdata(interface, dev); | 376 | usb_set_intfdata(interface, dev); |
377 | 377 | ||
378 | /* let the user know what node this device is now attached to */ | 378 | /* let the user know what node this device is now attached to */ |
379 | v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n", | 379 | v4l2_info(&dev->v4l2_dev, "device now attached to %s\n", |
380 | dev->video_dev->minor); | 380 | video_device_node_name(dev->video_dev)); |
381 | return 0; | 381 | return 0; |
382 | 382 | ||
383 | error: | 383 | error: |
@@ -391,13 +391,10 @@ error: | |||
391 | static void hdpvr_disconnect(struct usb_interface *interface) | 391 | static void hdpvr_disconnect(struct usb_interface *interface) |
392 | { | 392 | { |
393 | struct hdpvr_device *dev; | 393 | struct hdpvr_device *dev; |
394 | int minor; | ||
395 | 394 | ||
396 | dev = usb_get_intfdata(interface); | 395 | dev = usb_get_intfdata(interface); |
397 | usb_set_intfdata(interface, NULL); | 396 | usb_set_intfdata(interface, NULL); |
398 | 397 | ||
399 | minor = dev->video_dev->minor; | ||
400 | |||
401 | /* prevent more I/O from starting and stop any ongoing */ | 398 | /* prevent more I/O from starting and stop any ongoing */ |
402 | mutex_lock(&dev->io_mutex); | 399 | mutex_lock(&dev->io_mutex); |
403 | dev->status = STATUS_DISCONNECTED; | 400 | dev->status = STATUS_DISCONNECTED; |
@@ -425,7 +422,8 @@ static void hdpvr_disconnect(struct usb_interface *interface) | |||
425 | 422 | ||
426 | atomic_dec(&dev_nr); | 423 | atomic_dec(&dev_nr); |
427 | 424 | ||
428 | v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor); | 425 | v4l2_info(&dev->v4l2_dev, "device %s disconnected\n", |
426 | video_device_node_name(dev->video_dev)); | ||
429 | 427 | ||
430 | v4l2_device_unregister(&dev->v4l2_dev); | 428 | v4l2_device_unregister(&dev->v4l2_dev); |
431 | kfree(dev->usbc_buf); | 429 | kfree(dev->usbc_buf); |
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index b5439cabb38..fdd782039e9 100644 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ b/drivers/media/video/hdpvr/hdpvr-video.c | |||
@@ -523,7 +523,7 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) | |||
523 | 523 | ||
524 | mutex_lock(&dev->io_mutex); | 524 | mutex_lock(&dev->io_mutex); |
525 | 525 | ||
526 | if (video_is_unregistered(dev->video_dev)) { | 526 | if (!video_is_registered(dev->video_dev)) { |
527 | mutex_unlock(&dev->io_mutex); | 527 | mutex_unlock(&dev->io_mutex); |
528 | return -EIO; | 528 | return -EIO; |
529 | } | 529 | } |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 64360d26b32..b86e35386ce 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -353,6 +353,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
353 | ir_type = IR_TYPE_RC5; | 353 | ir_type = IR_TYPE_RC5; |
354 | ir_codes = &ir_codes_fusionhdtv_mce_table; | 354 | ir_codes = &ir_codes_fusionhdtv_mce_table; |
355 | break; | 355 | break; |
356 | case 0x0b: | ||
356 | case 0x47: | 357 | case 0x47: |
357 | case 0x71: | 358 | case 0x71: |
358 | if (adap->id == I2C_HW_B_CX2388x || | 359 | if (adap->id == I2C_HW_B_CX2388x || |
@@ -422,7 +423,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
422 | 423 | ||
423 | /* Make sure we are all setup before going on */ | 424 | /* Make sure we are all setup before going on */ |
424 | if (!name || !ir->get_key || !ir_type || !ir_codes) { | 425 | if (!name || !ir->get_key || !ir_type || !ir_codes) { |
425 | dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n", | 426 | dprintk(1, ": Unsupported device at address 0x%02x\n", |
426 | addr); | 427 | addr); |
427 | err = -ENODEV; | 428 | err = -ENODEV; |
428 | goto err_out_free; | 429 | goto err_out_free; |
@@ -437,7 +438,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
437 | dev_name(&client->dev)); | 438 | dev_name(&client->dev)); |
438 | 439 | ||
439 | /* init + register input device */ | 440 | /* init + register input device */ |
440 | err = ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); | 441 | err = ir_input_init(input_dev, &ir->ir, ir_type); |
441 | if (err < 0) | 442 | if (err < 0) |
442 | goto err_out_free; | 443 | goto err_out_free; |
443 | 444 | ||
@@ -445,7 +446,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
445 | input_dev->name = ir->name; | 446 | input_dev->name = ir->name; |
446 | input_dev->phys = ir->phys; | 447 | input_dev->phys = ir->phys; |
447 | 448 | ||
448 | err = input_register_device(ir->input); | 449 | err = ir_input_register(ir->input, ir->ir_codes); |
449 | if (err) | 450 | if (err) |
450 | goto err_out_free; | 451 | goto err_out_free; |
451 | 452 | ||
@@ -459,8 +460,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
459 | return 0; | 460 | return 0; |
460 | 461 | ||
461 | err_out_free: | 462 | err_out_free: |
462 | ir_input_free(input_dev); | ||
463 | input_free_device(input_dev); | ||
464 | kfree(ir); | 463 | kfree(ir); |
465 | return err; | 464 | return err; |
466 | } | 465 | } |
@@ -473,8 +472,7 @@ static int ir_remove(struct i2c_client *client) | |||
473 | cancel_delayed_work_sync(&ir->work); | 472 | cancel_delayed_work_sync(&ir->work); |
474 | 473 | ||
475 | /* unregister device */ | 474 | /* unregister device */ |
476 | ir_input_free(ir->input); | 475 | ir_input_unregister(ir->input); |
477 | input_unregister_device(ir->input); | ||
478 | 476 | ||
479 | /* free memory */ | 477 | /* free memory */ |
480 | kfree(ir); | 478 | kfree(ir); |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index e707ef3086b..babcabd73c0 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -985,8 +985,8 @@ int ivtv_v4l2_open(struct file *filp) | |||
985 | 985 | ||
986 | mutex_lock(&itv->serialize_lock); | 986 | mutex_lock(&itv->serialize_lock); |
987 | if (ivtv_init_on_first_open(itv)) { | 987 | if (ivtv_init_on_first_open(itv)) { |
988 | IVTV_ERR("Failed to initialize on minor %d\n", | 988 | IVTV_ERR("Failed to initialize on device %s\n", |
989 | vdev->minor); | 989 | video_device_node_name(vdev)); |
990 | mutex_unlock(&itv->serialize_lock); | 990 | mutex_unlock(&itv->serialize_lock); |
991 | return -ENXIO; | 991 | return -ENXIO; |
992 | } | 992 | } |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 67699e3f2aa..e12c6022373 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -245,6 +245,7 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) | |||
245 | { | 245 | { |
246 | struct ivtv_stream *s = &itv->streams[type]; | 246 | struct ivtv_stream *s = &itv->streams[type]; |
247 | int vfl_type = ivtv_stream_info[type].vfl_type; | 247 | int vfl_type = ivtv_stream_info[type].vfl_type; |
248 | const char *name; | ||
248 | int num; | 249 | int num; |
249 | 250 | ||
250 | if (s->vdev == NULL) | 251 | if (s->vdev == NULL) |
@@ -268,24 +269,24 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) | |||
268 | s->vdev = NULL; | 269 | s->vdev = NULL; |
269 | return -ENOMEM; | 270 | return -ENOMEM; |
270 | } | 271 | } |
271 | num = s->vdev->num; | 272 | name = video_device_node_name(s->vdev); |
272 | 273 | ||
273 | switch (vfl_type) { | 274 | switch (vfl_type) { |
274 | case VFL_TYPE_GRABBER: | 275 | case VFL_TYPE_GRABBER: |
275 | IVTV_INFO("Registered device video%d for %s (%d kB)\n", | 276 | IVTV_INFO("Registered device %s for %s (%d kB)\n", |
276 | num, s->name, itv->options.kilobytes[type]); | 277 | name, s->name, itv->options.kilobytes[type]); |
277 | break; | 278 | break; |
278 | case VFL_TYPE_RADIO: | 279 | case VFL_TYPE_RADIO: |
279 | IVTV_INFO("Registered device radio%d for %s\n", | 280 | IVTV_INFO("Registered device %s for %s\n", |
280 | num, s->name); | 281 | name, s->name); |
281 | break; | 282 | break; |
282 | case VFL_TYPE_VBI: | 283 | case VFL_TYPE_VBI: |
283 | if (itv->options.kilobytes[type]) | 284 | if (itv->options.kilobytes[type]) |
284 | IVTV_INFO("Registered device vbi%d for %s (%d kB)\n", | 285 | IVTV_INFO("Registered device %s for %s (%d kB)\n", |
285 | num, s->name, itv->options.kilobytes[type]); | 286 | name, s->name, itv->options.kilobytes[type]); |
286 | else | 287 | else |
287 | IVTV_INFO("Registered device vbi%d for %s\n", | 288 | IVTV_INFO("Registered device %s for %s\n", |
288 | num, s->name); | 289 | name, s->name); |
289 | break; | 290 | break; |
290 | } | 291 | } |
291 | return 0; | 292 | return 0; |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 01e1eefcf1e..6ffa64cd1c6 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
@@ -1681,7 +1681,6 @@ static struct video_device meye_template = { | |||
1681 | .fops = &meye_fops, | 1681 | .fops = &meye_fops, |
1682 | .ioctl_ops = &meye_ioctl_ops, | 1682 | .ioctl_ops = &meye_ioctl_ops, |
1683 | .release = video_device_release, | 1683 | .release = video_device_release, |
1684 | .minor = -1, | ||
1685 | }; | 1684 | }; |
1686 | 1685 | ||
1687 | #ifdef CONFIG_PM | 1686 | #ifdef CONFIG_PM |
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 45388d2ce2f..b62c0bd3f8e 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
@@ -17,9 +17,11 @@ | |||
17 | #include <media/v4l2-chip-ident.h> | 17 | #include <media/v4l2-chip-ident.h> |
18 | #include <media/soc_camera.h> | 18 | #include <media/soc_camera.h> |
19 | 19 | ||
20 | /* mt9m001 i2c address 0x5d | 20 | /* |
21 | * mt9m001 i2c address 0x5d | ||
21 | * The platform has to define ctruct i2c_board_info objects and link to them | 22 | * The platform has to define ctruct i2c_board_info objects and link to them |
22 | * from struct soc_camera_link */ | 23 | * from struct soc_camera_link |
24 | */ | ||
23 | 25 | ||
24 | /* mt9m001 selected register addresses */ | 26 | /* mt9m001 selected register addresses */ |
25 | #define MT9M001_CHIP_VERSION 0x00 | 27 | #define MT9M001_CHIP_VERSION 0x00 |
@@ -46,42 +48,50 @@ | |||
46 | #define MT9M001_COLUMN_SKIP 20 | 48 | #define MT9M001_COLUMN_SKIP 20 |
47 | #define MT9M001_ROW_SKIP 12 | 49 | #define MT9M001_ROW_SKIP 12 |
48 | 50 | ||
49 | static const struct soc_camera_data_format mt9m001_colour_formats[] = { | 51 | /* MT9M001 has only one fixed colorspace per pixelcode */ |
50 | /* Order important: first natively supported, | 52 | struct mt9m001_datafmt { |
51 | * second supported with a GPIO extender */ | 53 | enum v4l2_mbus_pixelcode code; |
52 | { | 54 | enum v4l2_colorspace colorspace; |
53 | .name = "Bayer (sRGB) 10 bit", | 55 | }; |
54 | .depth = 10, | 56 | |
55 | .fourcc = V4L2_PIX_FMT_SBGGR16, | 57 | /* Find a data format by a pixel code in an array */ |
56 | .colorspace = V4L2_COLORSPACE_SRGB, | 58 | static const struct mt9m001_datafmt *mt9m001_find_datafmt( |
57 | }, { | 59 | enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt, |
58 | .name = "Bayer (sRGB) 8 bit", | 60 | int n) |
59 | .depth = 8, | 61 | { |
60 | .fourcc = V4L2_PIX_FMT_SBGGR8, | 62 | int i; |
61 | .colorspace = V4L2_COLORSPACE_SRGB, | 63 | for (i = 0; i < n; i++) |
62 | } | 64 | if (fmt[i].code == code) |
65 | return fmt + i; | ||
66 | |||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | static const struct mt9m001_datafmt mt9m001_colour_fmts[] = { | ||
71 | /* | ||
72 | * Order important: first natively supported, | ||
73 | * second supported with a GPIO extender | ||
74 | */ | ||
75 | {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, | ||
76 | {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, | ||
63 | }; | 77 | }; |
64 | 78 | ||
65 | static const struct soc_camera_data_format mt9m001_monochrome_formats[] = { | 79 | static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = { |
66 | /* Order important - see above */ | 80 | /* Order important - see above */ |
67 | { | 81 | {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, |
68 | .name = "Monochrome 10 bit", | 82 | {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, |
69 | .depth = 10, | ||
70 | .fourcc = V4L2_PIX_FMT_Y16, | ||
71 | }, { | ||
72 | .name = "Monochrome 8 bit", | ||
73 | .depth = 8, | ||
74 | .fourcc = V4L2_PIX_FMT_GREY, | ||
75 | }, | ||
76 | }; | 83 | }; |
77 | 84 | ||
78 | struct mt9m001 { | 85 | struct mt9m001 { |
79 | struct v4l2_subdev subdev; | 86 | struct v4l2_subdev subdev; |
80 | struct v4l2_rect rect; /* Sensor window */ | 87 | struct v4l2_rect rect; /* Sensor window */ |
81 | __u32 fourcc; | 88 | const struct mt9m001_datafmt *fmt; |
89 | const struct mt9m001_datafmt *fmts; | ||
90 | int num_fmts; | ||
82 | int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ | 91 | int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ |
83 | unsigned int gain; | 92 | unsigned int gain; |
84 | unsigned int exposure; | 93 | unsigned int exposure; |
94 | unsigned short y_skip_top; /* Lines to skip at the top */ | ||
85 | unsigned char autoexposure; | 95 | unsigned char autoexposure; |
86 | }; | 96 | }; |
87 | 97 | ||
@@ -204,8 +214,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
204 | const u16 hblank = 9, vblank = 25; | 214 | const u16 hblank = 9, vblank = 25; |
205 | unsigned int total_h; | 215 | unsigned int total_h; |
206 | 216 | ||
207 | if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 || | 217 | if (mt9m001->fmts == mt9m001_colour_fmts) |
208 | mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16) | ||
209 | /* | 218 | /* |
210 | * Bayer format - even number of rows for simplicity, | 219 | * Bayer format - even number of rows for simplicity, |
211 | * but let the user play with the top row. | 220 | * but let the user play with the top row. |
@@ -222,15 +231,17 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
222 | soc_camera_limit_side(&rect.top, &rect.height, | 231 | soc_camera_limit_side(&rect.top, &rect.height, |
223 | MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT); | 232 | MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT); |
224 | 233 | ||
225 | total_h = rect.height + icd->y_skip_top + vblank; | 234 | total_h = rect.height + mt9m001->y_skip_top + vblank; |
226 | 235 | ||
227 | /* Blanking and start values - default... */ | 236 | /* Blanking and start values - default... */ |
228 | ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); | 237 | ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); |
229 | if (!ret) | 238 | if (!ret) |
230 | ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank); | 239 | ret = reg_write(client, MT9M001_VERTICAL_BLANKING, vblank); |
231 | 240 | ||
232 | /* The caller provides a supported format, as verified per | 241 | /* |
233 | * call to icd->try_fmt() */ | 242 | * The caller provides a supported format, as verified per |
243 | * call to icd->try_fmt() | ||
244 | */ | ||
234 | if (!ret) | 245 | if (!ret) |
235 | ret = reg_write(client, MT9M001_COLUMN_START, rect.left); | 246 | ret = reg_write(client, MT9M001_COLUMN_START, rect.left); |
236 | if (!ret) | 247 | if (!ret) |
@@ -239,7 +250,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
239 | ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1); | 250 | ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1); |
240 | if (!ret) | 251 | if (!ret) |
241 | ret = reg_write(client, MT9M001_WINDOW_HEIGHT, | 252 | ret = reg_write(client, MT9M001_WINDOW_HEIGHT, |
242 | rect.height + icd->y_skip_top - 1); | 253 | rect.height + mt9m001->y_skip_top - 1); |
243 | if (!ret && mt9m001->autoexposure) { | 254 | if (!ret && mt9m001->autoexposure) { |
244 | ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h); | 255 | ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h); |
245 | if (!ret) { | 256 | if (!ret) { |
@@ -283,32 +294,32 @@ static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
283 | return 0; | 294 | return 0; |
284 | } | 295 | } |
285 | 296 | ||
286 | static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 297 | static int mt9m001_g_fmt(struct v4l2_subdev *sd, |
298 | struct v4l2_mbus_framefmt *mf) | ||
287 | { | 299 | { |
288 | struct i2c_client *client = sd->priv; | 300 | struct i2c_client *client = sd->priv; |
289 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 301 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
290 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
291 | 302 | ||
292 | pix->width = mt9m001->rect.width; | 303 | mf->width = mt9m001->rect.width; |
293 | pix->height = mt9m001->rect.height; | 304 | mf->height = mt9m001->rect.height; |
294 | pix->pixelformat = mt9m001->fourcc; | 305 | mf->code = mt9m001->fmt->code; |
295 | pix->field = V4L2_FIELD_NONE; | 306 | mf->colorspace = mt9m001->fmt->colorspace; |
296 | pix->colorspace = V4L2_COLORSPACE_SRGB; | 307 | mf->field = V4L2_FIELD_NONE; |
297 | 308 | ||
298 | return 0; | 309 | return 0; |
299 | } | 310 | } |
300 | 311 | ||
301 | static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 312 | static int mt9m001_s_fmt(struct v4l2_subdev *sd, |
313 | struct v4l2_mbus_framefmt *mf) | ||
302 | { | 314 | { |
303 | struct i2c_client *client = sd->priv; | 315 | struct i2c_client *client = sd->priv; |
304 | struct mt9m001 *mt9m001 = to_mt9m001(client); | 316 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
305 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
306 | struct v4l2_crop a = { | 317 | struct v4l2_crop a = { |
307 | .c = { | 318 | .c = { |
308 | .left = mt9m001->rect.left, | 319 | .left = mt9m001->rect.left, |
309 | .top = mt9m001->rect.top, | 320 | .top = mt9m001->rect.top, |
310 | .width = pix->width, | 321 | .width = mf->width, |
311 | .height = pix->height, | 322 | .height = mf->height, |
312 | }, | 323 | }, |
313 | }; | 324 | }; |
314 | int ret; | 325 | int ret; |
@@ -316,28 +327,39 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |||
316 | /* No support for scaling so far, just crop. TODO: use skipping */ | 327 | /* No support for scaling so far, just crop. TODO: use skipping */ |
317 | ret = mt9m001_s_crop(sd, &a); | 328 | ret = mt9m001_s_crop(sd, &a); |
318 | if (!ret) { | 329 | if (!ret) { |
319 | pix->width = mt9m001->rect.width; | 330 | mf->width = mt9m001->rect.width; |
320 | pix->height = mt9m001->rect.height; | 331 | mf->height = mt9m001->rect.height; |
321 | mt9m001->fourcc = pix->pixelformat; | 332 | mt9m001->fmt = mt9m001_find_datafmt(mf->code, |
333 | mt9m001->fmts, mt9m001->num_fmts); | ||
334 | mf->colorspace = mt9m001->fmt->colorspace; | ||
322 | } | 335 | } |
323 | 336 | ||
324 | return ret; | 337 | return ret; |
325 | } | 338 | } |
326 | 339 | ||
327 | static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 340 | static int mt9m001_try_fmt(struct v4l2_subdev *sd, |
341 | struct v4l2_mbus_framefmt *mf) | ||
328 | { | 342 | { |
329 | struct i2c_client *client = sd->priv; | 343 | struct i2c_client *client = sd->priv; |
330 | struct soc_camera_device *icd = client->dev.platform_data; | 344 | struct mt9m001 *mt9m001 = to_mt9m001(client); |
331 | struct v4l2_pix_format *pix = &f->fmt.pix; | 345 | const struct mt9m001_datafmt *fmt; |
332 | 346 | ||
333 | v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH, | 347 | v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH, |
334 | MT9M001_MAX_WIDTH, 1, | 348 | MT9M001_MAX_WIDTH, 1, |
335 | &pix->height, MT9M001_MIN_HEIGHT + icd->y_skip_top, | 349 | &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top, |
336 | MT9M001_MAX_HEIGHT + icd->y_skip_top, 0, 0); | 350 | MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0); |
351 | |||
352 | if (mt9m001->fmts == mt9m001_colour_fmts) | ||
353 | mf->height = ALIGN(mf->height - 1, 2); | ||
337 | 354 | ||
338 | if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || | 355 | fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts, |
339 | pix->pixelformat == V4L2_PIX_FMT_SBGGR16) | 356 | mt9m001->num_fmts); |
340 | pix->height = ALIGN(pix->height - 1, 2); | 357 | if (!fmt) { |
358 | fmt = mt9m001->fmt; | ||
359 | mf->code = fmt->code; | ||
360 | } | ||
361 | |||
362 | mf->colorspace = fmt->colorspace; | ||
341 | 363 | ||
342 | return 0; | 364 | return 0; |
343 | } | 365 | } |
@@ -552,7 +574,7 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
552 | if (ctrl->value) { | 574 | if (ctrl->value) { |
553 | const u16 vblank = 25; | 575 | const u16 vblank = 25; |
554 | unsigned int total_h = mt9m001->rect.height + | 576 | unsigned int total_h = mt9m001->rect.height + |
555 | icd->y_skip_top + vblank; | 577 | mt9m001->y_skip_top + vblank; |
556 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, | 578 | if (reg_write(client, MT9M001_SHUTTER_WIDTH, |
557 | total_h) < 0) | 579 | total_h) < 0) |
558 | return -EIO; | 580 | return -EIO; |
@@ -568,8 +590,10 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
568 | return 0; | 590 | return 0; |
569 | } | 591 | } |
570 | 592 | ||
571 | /* Interface active, can use i2c. If it fails, it can indeed mean, that | 593 | /* |
572 | * this wasn't our capture interface, so, we wait for the right one */ | 594 | * Interface active, can use i2c. If it fails, it can indeed mean, that |
595 | * this wasn't our capture interface, so, we wait for the right one | ||
596 | */ | ||
573 | static int mt9m001_video_probe(struct soc_camera_device *icd, | 597 | static int mt9m001_video_probe(struct soc_camera_device *icd, |
574 | struct i2c_client *client) | 598 | struct i2c_client *client) |
575 | { | 599 | { |
@@ -579,8 +603,10 @@ static int mt9m001_video_probe(struct soc_camera_device *icd, | |||
579 | unsigned long flags; | 603 | unsigned long flags; |
580 | int ret; | 604 | int ret; |
581 | 605 | ||
582 | /* We must have a parent by now. And it cannot be a wrong one. | 606 | /* |
583 | * So this entire test is completely redundant. */ | 607 | * We must have a parent by now. And it cannot be a wrong one. |
608 | * So this entire test is completely redundant. | ||
609 | */ | ||
584 | if (!icd->dev.parent || | 610 | if (!icd->dev.parent || |
585 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) | 611 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) |
586 | return -ENODEV; | 612 | return -ENODEV; |
@@ -597,11 +623,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd, | |||
597 | case 0x8411: | 623 | case 0x8411: |
598 | case 0x8421: | 624 | case 0x8421: |
599 | mt9m001->model = V4L2_IDENT_MT9M001C12ST; | 625 | mt9m001->model = V4L2_IDENT_MT9M001C12ST; |
600 | icd->formats = mt9m001_colour_formats; | 626 | mt9m001->fmts = mt9m001_colour_fmts; |
601 | break; | 627 | break; |
602 | case 0x8431: | 628 | case 0x8431: |
603 | mt9m001->model = V4L2_IDENT_MT9M001C12STM; | 629 | mt9m001->model = V4L2_IDENT_MT9M001C12STM; |
604 | icd->formats = mt9m001_monochrome_formats; | 630 | mt9m001->fmts = mt9m001_monochrome_fmts; |
605 | break; | 631 | break; |
606 | default: | 632 | default: |
607 | dev_err(&client->dev, | 633 | dev_err(&client->dev, |
@@ -609,7 +635,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd, | |||
609 | return -ENODEV; | 635 | return -ENODEV; |
610 | } | 636 | } |
611 | 637 | ||
612 | icd->num_formats = 0; | 638 | mt9m001->num_fmts = 0; |
613 | 639 | ||
614 | /* | 640 | /* |
615 | * This is a 10bit sensor, so by default we only allow 10bit. | 641 | * This is a 10bit sensor, so by default we only allow 10bit. |
@@ -622,14 +648,14 @@ static int mt9m001_video_probe(struct soc_camera_device *icd, | |||
622 | flags = SOCAM_DATAWIDTH_10; | 648 | flags = SOCAM_DATAWIDTH_10; |
623 | 649 | ||
624 | if (flags & SOCAM_DATAWIDTH_10) | 650 | if (flags & SOCAM_DATAWIDTH_10) |
625 | icd->num_formats++; | 651 | mt9m001->num_fmts++; |
626 | else | 652 | else |
627 | icd->formats++; | 653 | mt9m001->fmts++; |
628 | 654 | ||
629 | if (flags & SOCAM_DATAWIDTH_8) | 655 | if (flags & SOCAM_DATAWIDTH_8) |
630 | icd->num_formats++; | 656 | mt9m001->num_fmts++; |
631 | 657 | ||
632 | mt9m001->fourcc = icd->formats->fourcc; | 658 | mt9m001->fmt = &mt9m001->fmts[0]; |
633 | 659 | ||
634 | dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, | 660 | dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, |
635 | data == 0x8431 ? "C12STM" : "C12ST"); | 661 | data == 0x8431 ? "C12STM" : "C12ST"); |
@@ -655,6 +681,16 @@ static void mt9m001_video_remove(struct soc_camera_device *icd) | |||
655 | icl->free_bus(icl); | 681 | icl->free_bus(icl); |
656 | } | 682 | } |
657 | 683 | ||
684 | static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) | ||
685 | { | ||
686 | struct i2c_client *client = sd->priv; | ||
687 | struct mt9m001 *mt9m001 = to_mt9m001(client); | ||
688 | |||
689 | *lines = mt9m001->y_skip_top; | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
658 | static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { | 694 | static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { |
659 | .g_ctrl = mt9m001_g_ctrl, | 695 | .g_ctrl = mt9m001_g_ctrl, |
660 | .s_ctrl = mt9m001_s_ctrl, | 696 | .s_ctrl = mt9m001_s_ctrl, |
@@ -665,19 +701,38 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { | |||
665 | #endif | 701 | #endif |
666 | }; | 702 | }; |
667 | 703 | ||
704 | static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index, | ||
705 | enum v4l2_mbus_pixelcode *code) | ||
706 | { | ||
707 | struct i2c_client *client = sd->priv; | ||
708 | struct mt9m001 *mt9m001 = to_mt9m001(client); | ||
709 | |||
710 | if ((unsigned int)index >= mt9m001->num_fmts) | ||
711 | return -EINVAL; | ||
712 | |||
713 | *code = mt9m001->fmts[index].code; | ||
714 | return 0; | ||
715 | } | ||
716 | |||
668 | static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { | 717 | static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { |
669 | .s_stream = mt9m001_s_stream, | 718 | .s_stream = mt9m001_s_stream, |
670 | .s_fmt = mt9m001_s_fmt, | 719 | .s_mbus_fmt = mt9m001_s_fmt, |
671 | .g_fmt = mt9m001_g_fmt, | 720 | .g_mbus_fmt = mt9m001_g_fmt, |
672 | .try_fmt = mt9m001_try_fmt, | 721 | .try_mbus_fmt = mt9m001_try_fmt, |
673 | .s_crop = mt9m001_s_crop, | 722 | .s_crop = mt9m001_s_crop, |
674 | .g_crop = mt9m001_g_crop, | 723 | .g_crop = mt9m001_g_crop, |
675 | .cropcap = mt9m001_cropcap, | 724 | .cropcap = mt9m001_cropcap, |
725 | .enum_mbus_fmt = mt9m001_enum_fmt, | ||
726 | }; | ||
727 | |||
728 | static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { | ||
729 | .g_skip_top_lines = mt9m001_g_skip_top_lines, | ||
676 | }; | 730 | }; |
677 | 731 | ||
678 | static struct v4l2_subdev_ops mt9m001_subdev_ops = { | 732 | static struct v4l2_subdev_ops mt9m001_subdev_ops = { |
679 | .core = &mt9m001_subdev_core_ops, | 733 | .core = &mt9m001_subdev_core_ops, |
680 | .video = &mt9m001_subdev_video_ops, | 734 | .video = &mt9m001_subdev_video_ops, |
735 | .sensor = &mt9m001_subdev_sensor_ops, | ||
681 | }; | 736 | }; |
682 | 737 | ||
683 | static int mt9m001_probe(struct i2c_client *client, | 738 | static int mt9m001_probe(struct i2c_client *client, |
@@ -714,15 +769,17 @@ static int mt9m001_probe(struct i2c_client *client, | |||
714 | 769 | ||
715 | /* Second stage probe - when a capture adapter is there */ | 770 | /* Second stage probe - when a capture adapter is there */ |
716 | icd->ops = &mt9m001_ops; | 771 | icd->ops = &mt9m001_ops; |
717 | icd->y_skip_top = 0; | ||
718 | 772 | ||
773 | mt9m001->y_skip_top = 0; | ||
719 | mt9m001->rect.left = MT9M001_COLUMN_SKIP; | 774 | mt9m001->rect.left = MT9M001_COLUMN_SKIP; |
720 | mt9m001->rect.top = MT9M001_ROW_SKIP; | 775 | mt9m001->rect.top = MT9M001_ROW_SKIP; |
721 | mt9m001->rect.width = MT9M001_MAX_WIDTH; | 776 | mt9m001->rect.width = MT9M001_MAX_WIDTH; |
722 | mt9m001->rect.height = MT9M001_MAX_HEIGHT; | 777 | mt9m001->rect.height = MT9M001_MAX_HEIGHT; |
723 | 778 | ||
724 | /* Simulated autoexposure. If enabled, we calculate shutter width | 779 | /* |
725 | * ourselves in the driver based on vertical blanking and frame width */ | 780 | * Simulated autoexposure. If enabled, we calculate shutter width |
781 | * ourselves in the driver based on vertical blanking and frame width | ||
782 | */ | ||
726 | mt9m001->autoexposure = 1; | 783 | mt9m001->autoexposure = 1; |
727 | 784 | ||
728 | ret = mt9m001_video_probe(icd, client); | 785 | ret = mt9m001_video_probe(icd, client); |
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 90da699601e..d35f536f9fc 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -123,23 +123,34 @@ | |||
123 | #define MT9M111_MAX_HEIGHT 1024 | 123 | #define MT9M111_MAX_HEIGHT 1024 |
124 | #define MT9M111_MAX_WIDTH 1280 | 124 | #define MT9M111_MAX_WIDTH 1280 |
125 | 125 | ||
126 | #define COL_FMT(_name, _depth, _fourcc, _colorspace) \ | 126 | /* MT9M111 has only one fixed colorspace per pixelcode */ |
127 | { .name = _name, .depth = _depth, .fourcc = _fourcc, \ | 127 | struct mt9m111_datafmt { |
128 | .colorspace = _colorspace } | 128 | enum v4l2_mbus_pixelcode code; |
129 | #define RGB_FMT(_name, _depth, _fourcc) \ | 129 | enum v4l2_colorspace colorspace; |
130 | COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB) | 130 | }; |
131 | #define JPG_FMT(_name, _depth, _fourcc) \ | 131 | |
132 | COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) | 132 | /* Find a data format by a pixel code in an array */ |
133 | 133 | static const struct mt9m111_datafmt *mt9m111_find_datafmt( | |
134 | static const struct soc_camera_data_format mt9m111_colour_formats[] = { | 134 | enum v4l2_mbus_pixelcode code, const struct mt9m111_datafmt *fmt, |
135 | JPG_FMT("CbYCrY 16 bit", 16, V4L2_PIX_FMT_UYVY), | 135 | int n) |
136 | JPG_FMT("CrYCbY 16 bit", 16, V4L2_PIX_FMT_VYUY), | 136 | { |
137 | JPG_FMT("YCbYCr 16 bit", 16, V4L2_PIX_FMT_YUYV), | 137 | int i; |
138 | JPG_FMT("YCrYCb 16 bit", 16, V4L2_PIX_FMT_YVYU), | 138 | for (i = 0; i < n; i++) |
139 | RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565), | 139 | if (fmt[i].code == code) |
140 | RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555), | 140 | return fmt + i; |
141 | RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16), | 141 | |
142 | RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8), | 142 | return NULL; |
143 | } | ||
144 | |||
145 | static const struct mt9m111_datafmt mt9m111_colour_fmts[] = { | ||
146 | {V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG}, | ||
147 | {V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG}, | ||
148 | {V4L2_MBUS_FMT_YUYV8_2X8_BE, V4L2_COLORSPACE_JPEG}, | ||
149 | {V4L2_MBUS_FMT_YVYU8_2X8_BE, V4L2_COLORSPACE_JPEG}, | ||
150 | {V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, | ||
151 | {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, | ||
152 | {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, | ||
153 | {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, | ||
143 | }; | 154 | }; |
144 | 155 | ||
145 | enum mt9m111_context { | 156 | enum mt9m111_context { |
@@ -152,7 +163,7 @@ struct mt9m111 { | |||
152 | int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ | 163 | int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ |
153 | enum mt9m111_context context; | 164 | enum mt9m111_context context; |
154 | struct v4l2_rect rect; | 165 | struct v4l2_rect rect; |
155 | u32 pixfmt; | 166 | const struct mt9m111_datafmt *fmt; |
156 | unsigned int gain; | 167 | unsigned int gain; |
157 | unsigned char autoexposure; | 168 | unsigned char autoexposure; |
158 | unsigned char datawidth; | 169 | unsigned char datawidth; |
@@ -258,8 +269,8 @@ static int mt9m111_setup_rect(struct i2c_client *client, | |||
258 | int width = rect->width; | 269 | int width = rect->width; |
259 | int height = rect->height; | 270 | int height = rect->height; |
260 | 271 | ||
261 | if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 || | 272 | if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || |
262 | mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) | 273 | mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) |
263 | is_raw_format = 1; | 274 | is_raw_format = 1; |
264 | else | 275 | else |
265 | is_raw_format = 0; | 276 | is_raw_format = 0; |
@@ -307,7 +318,8 @@ static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt) | |||
307 | 318 | ||
308 | static int mt9m111_setfmt_bayer8(struct i2c_client *client) | 319 | static int mt9m111_setfmt_bayer8(struct i2c_client *client) |
309 | { | 320 | { |
310 | return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER); | 321 | return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER | |
322 | MT9M111_OUTFMT_RGB); | ||
311 | } | 323 | } |
312 | 324 | ||
313 | static int mt9m111_setfmt_bayer10(struct i2c_client *client) | 325 | static int mt9m111_setfmt_bayer10(struct i2c_client *client) |
@@ -401,8 +413,8 @@ static int mt9m111_make_rect(struct i2c_client *client, | |||
401 | { | 413 | { |
402 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 414 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
403 | 415 | ||
404 | if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 || | 416 | if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || |
405 | mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) { | 417 | mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { |
406 | /* Bayer format - even size lengths */ | 418 | /* Bayer format - even size lengths */ |
407 | rect->width = ALIGN(rect->width, 2); | 419 | rect->width = ALIGN(rect->width, 2); |
408 | rect->height = ALIGN(rect->height, 2); | 420 | rect->height = ALIGN(rect->height, 2); |
@@ -460,120 +472,139 @@ static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
460 | return 0; | 472 | return 0; |
461 | } | 473 | } |
462 | 474 | ||
463 | static int mt9m111_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 475 | static int mt9m111_g_fmt(struct v4l2_subdev *sd, |
476 | struct v4l2_mbus_framefmt *mf) | ||
464 | { | 477 | { |
465 | struct i2c_client *client = sd->priv; | 478 | struct i2c_client *client = sd->priv; |
466 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 479 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
467 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
468 | 480 | ||
469 | pix->width = mt9m111->rect.width; | 481 | mf->width = mt9m111->rect.width; |
470 | pix->height = mt9m111->rect.height; | 482 | mf->height = mt9m111->rect.height; |
471 | pix->pixelformat = mt9m111->pixfmt; | 483 | mf->code = mt9m111->fmt->code; |
472 | pix->field = V4L2_FIELD_NONE; | 484 | mf->field = V4L2_FIELD_NONE; |
473 | pix->colorspace = V4L2_COLORSPACE_SRGB; | ||
474 | 485 | ||
475 | return 0; | 486 | return 0; |
476 | } | 487 | } |
477 | 488 | ||
478 | static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt) | 489 | static int mt9m111_set_pixfmt(struct i2c_client *client, |
490 | enum v4l2_mbus_pixelcode code) | ||
479 | { | 491 | { |
480 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 492 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
481 | int ret; | 493 | int ret; |
482 | 494 | ||
483 | switch (pixfmt) { | 495 | switch (code) { |
484 | case V4L2_PIX_FMT_SBGGR8: | 496 | case V4L2_MBUS_FMT_SBGGR8_1X8: |
485 | ret = mt9m111_setfmt_bayer8(client); | 497 | ret = mt9m111_setfmt_bayer8(client); |
486 | break; | 498 | break; |
487 | case V4L2_PIX_FMT_SBGGR16: | 499 | case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: |
488 | ret = mt9m111_setfmt_bayer10(client); | 500 | ret = mt9m111_setfmt_bayer10(client); |
489 | break; | 501 | break; |
490 | case V4L2_PIX_FMT_RGB555: | 502 | case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: |
491 | ret = mt9m111_setfmt_rgb555(client); | 503 | ret = mt9m111_setfmt_rgb555(client); |
492 | break; | 504 | break; |
493 | case V4L2_PIX_FMT_RGB565: | 505 | case V4L2_MBUS_FMT_RGB565_2X8_LE: |
494 | ret = mt9m111_setfmt_rgb565(client); | 506 | ret = mt9m111_setfmt_rgb565(client); |
495 | break; | 507 | break; |
496 | case V4L2_PIX_FMT_UYVY: | 508 | case V4L2_MBUS_FMT_YUYV8_2X8_BE: |
497 | mt9m111->swap_yuv_y_chromas = 0; | 509 | mt9m111->swap_yuv_y_chromas = 0; |
498 | mt9m111->swap_yuv_cb_cr = 0; | 510 | mt9m111->swap_yuv_cb_cr = 0; |
499 | ret = mt9m111_setfmt_yuv(client); | 511 | ret = mt9m111_setfmt_yuv(client); |
500 | break; | 512 | break; |
501 | case V4L2_PIX_FMT_VYUY: | 513 | case V4L2_MBUS_FMT_YVYU8_2X8_BE: |
502 | mt9m111->swap_yuv_y_chromas = 0; | 514 | mt9m111->swap_yuv_y_chromas = 0; |
503 | mt9m111->swap_yuv_cb_cr = 1; | 515 | mt9m111->swap_yuv_cb_cr = 1; |
504 | ret = mt9m111_setfmt_yuv(client); | 516 | ret = mt9m111_setfmt_yuv(client); |
505 | break; | 517 | break; |
506 | case V4L2_PIX_FMT_YUYV: | 518 | case V4L2_MBUS_FMT_YUYV8_2X8_LE: |
507 | mt9m111->swap_yuv_y_chromas = 1; | 519 | mt9m111->swap_yuv_y_chromas = 1; |
508 | mt9m111->swap_yuv_cb_cr = 0; | 520 | mt9m111->swap_yuv_cb_cr = 0; |
509 | ret = mt9m111_setfmt_yuv(client); | 521 | ret = mt9m111_setfmt_yuv(client); |
510 | break; | 522 | break; |
511 | case V4L2_PIX_FMT_YVYU: | 523 | case V4L2_MBUS_FMT_YVYU8_2X8_LE: |
512 | mt9m111->swap_yuv_y_chromas = 1; | 524 | mt9m111->swap_yuv_y_chromas = 1; |
513 | mt9m111->swap_yuv_cb_cr = 1; | 525 | mt9m111->swap_yuv_cb_cr = 1; |
514 | ret = mt9m111_setfmt_yuv(client); | 526 | ret = mt9m111_setfmt_yuv(client); |
515 | break; | 527 | break; |
516 | default: | 528 | default: |
517 | dev_err(&client->dev, "Pixel format not handled : %x\n", | 529 | dev_err(&client->dev, "Pixel format not handled : %x\n", |
518 | pixfmt); | 530 | code); |
519 | ret = -EINVAL; | 531 | ret = -EINVAL; |
520 | } | 532 | } |
521 | 533 | ||
522 | if (!ret) | ||
523 | mt9m111->pixfmt = pixfmt; | ||
524 | |||
525 | return ret; | 534 | return ret; |
526 | } | 535 | } |
527 | 536 | ||
528 | static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 537 | static int mt9m111_s_fmt(struct v4l2_subdev *sd, |
538 | struct v4l2_mbus_framefmt *mf) | ||
529 | { | 539 | { |
530 | struct i2c_client *client = sd->priv; | 540 | struct i2c_client *client = sd->priv; |
541 | const struct mt9m111_datafmt *fmt; | ||
531 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 542 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
532 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
533 | struct v4l2_rect rect = { | 543 | struct v4l2_rect rect = { |
534 | .left = mt9m111->rect.left, | 544 | .left = mt9m111->rect.left, |
535 | .top = mt9m111->rect.top, | 545 | .top = mt9m111->rect.top, |
536 | .width = pix->width, | 546 | .width = mf->width, |
537 | .height = pix->height, | 547 | .height = mf->height, |
538 | }; | 548 | }; |
539 | int ret; | 549 | int ret; |
540 | 550 | ||
551 | fmt = mt9m111_find_datafmt(mf->code, mt9m111_colour_fmts, | ||
552 | ARRAY_SIZE(mt9m111_colour_fmts)); | ||
553 | if (!fmt) | ||
554 | return -EINVAL; | ||
555 | |||
541 | dev_dbg(&client->dev, | 556 | dev_dbg(&client->dev, |
542 | "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__, | 557 | "%s code=%x left=%d, top=%d, width=%d, height=%d\n", __func__, |
543 | pix->pixelformat, rect.left, rect.top, rect.width, rect.height); | 558 | mf->code, rect.left, rect.top, rect.width, rect.height); |
544 | 559 | ||
545 | ret = mt9m111_make_rect(client, &rect); | 560 | ret = mt9m111_make_rect(client, &rect); |
546 | if (!ret) | 561 | if (!ret) |
547 | ret = mt9m111_set_pixfmt(client, pix->pixelformat); | 562 | ret = mt9m111_set_pixfmt(client, mf->code); |
548 | if (!ret) | 563 | if (!ret) { |
549 | mt9m111->rect = rect; | 564 | mt9m111->rect = rect; |
565 | mt9m111->fmt = fmt; | ||
566 | mf->colorspace = fmt->colorspace; | ||
567 | } | ||
568 | |||
550 | return ret; | 569 | return ret; |
551 | } | 570 | } |
552 | 571 | ||
553 | static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 572 | static int mt9m111_try_fmt(struct v4l2_subdev *sd, |
573 | struct v4l2_mbus_framefmt *mf) | ||
554 | { | 574 | { |
555 | struct v4l2_pix_format *pix = &f->fmt.pix; | 575 | struct i2c_client *client = sd->priv; |
556 | bool bayer = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || | 576 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
557 | pix->pixelformat == V4L2_PIX_FMT_SBGGR16; | 577 | const struct mt9m111_datafmt *fmt; |
578 | bool bayer = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || | ||
579 | mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE; | ||
580 | |||
581 | fmt = mt9m111_find_datafmt(mf->code, mt9m111_colour_fmts, | ||
582 | ARRAY_SIZE(mt9m111_colour_fmts)); | ||
583 | if (!fmt) { | ||
584 | fmt = mt9m111->fmt; | ||
585 | mf->code = fmt->code; | ||
586 | } | ||
558 | 587 | ||
559 | /* | 588 | /* |
560 | * With Bayer format enforce even side lengths, but let the user play | 589 | * With Bayer format enforce even side lengths, but let the user play |
561 | * with the starting pixel | 590 | * with the starting pixel |
562 | */ | 591 | */ |
563 | 592 | ||
564 | if (pix->height > MT9M111_MAX_HEIGHT) | 593 | if (mf->height > MT9M111_MAX_HEIGHT) |
565 | pix->height = MT9M111_MAX_HEIGHT; | 594 | mf->height = MT9M111_MAX_HEIGHT; |
566 | else if (pix->height < 2) | 595 | else if (mf->height < 2) |
567 | pix->height = 2; | 596 | mf->height = 2; |
568 | else if (bayer) | 597 | else if (bayer) |
569 | pix->height = ALIGN(pix->height, 2); | 598 | mf->height = ALIGN(mf->height, 2); |
570 | 599 | ||
571 | if (pix->width > MT9M111_MAX_WIDTH) | 600 | if (mf->width > MT9M111_MAX_WIDTH) |
572 | pix->width = MT9M111_MAX_WIDTH; | 601 | mf->width = MT9M111_MAX_WIDTH; |
573 | else if (pix->width < 2) | 602 | else if (mf->width < 2) |
574 | pix->width = 2; | 603 | mf->width = 2; |
575 | else if (bayer) | 604 | else if (bayer) |
576 | pix->width = ALIGN(pix->width, 2); | 605 | mf->width = ALIGN(mf->width, 2); |
606 | |||
607 | mf->colorspace = fmt->colorspace; | ||
577 | 608 | ||
578 | return 0; | 609 | return 0; |
579 | } | 610 | } |
@@ -863,7 +894,7 @@ static int mt9m111_restore_state(struct i2c_client *client) | |||
863 | struct mt9m111 *mt9m111 = to_mt9m111(client); | 894 | struct mt9m111 *mt9m111 = to_mt9m111(client); |
864 | 895 | ||
865 | mt9m111_set_context(client, mt9m111->context); | 896 | mt9m111_set_context(client, mt9m111->context); |
866 | mt9m111_set_pixfmt(client, mt9m111->pixfmt); | 897 | mt9m111_set_pixfmt(client, mt9m111->fmt->code); |
867 | mt9m111_setup_rect(client, &mt9m111->rect); | 898 | mt9m111_setup_rect(client, &mt9m111->rect); |
868 | mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); | 899 | mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); |
869 | mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); | 900 | mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); |
@@ -952,9 +983,6 @@ static int mt9m111_video_probe(struct soc_camera_device *icd, | |||
952 | goto ei2c; | 983 | goto ei2c; |
953 | } | 984 | } |
954 | 985 | ||
955 | icd->formats = mt9m111_colour_formats; | ||
956 | icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); | ||
957 | |||
958 | dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data); | 986 | dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data); |
959 | 987 | ||
960 | ei2c: | 988 | ei2c: |
@@ -971,13 +999,24 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { | |||
971 | #endif | 999 | #endif |
972 | }; | 1000 | }; |
973 | 1001 | ||
1002 | static int mt9m111_enum_fmt(struct v4l2_subdev *sd, int index, | ||
1003 | enum v4l2_mbus_pixelcode *code) | ||
1004 | { | ||
1005 | if ((unsigned int)index >= ARRAY_SIZE(mt9m111_colour_fmts)) | ||
1006 | return -EINVAL; | ||
1007 | |||
1008 | *code = mt9m111_colour_fmts[index].code; | ||
1009 | return 0; | ||
1010 | } | ||
1011 | |||
974 | static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { | 1012 | static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { |
975 | .s_fmt = mt9m111_s_fmt, | 1013 | .s_mbus_fmt = mt9m111_s_fmt, |
976 | .g_fmt = mt9m111_g_fmt, | 1014 | .g_mbus_fmt = mt9m111_g_fmt, |
977 | .try_fmt = mt9m111_try_fmt, | 1015 | .try_mbus_fmt = mt9m111_try_fmt, |
978 | .s_crop = mt9m111_s_crop, | 1016 | .s_crop = mt9m111_s_crop, |
979 | .g_crop = mt9m111_g_crop, | 1017 | .g_crop = mt9m111_g_crop, |
980 | .cropcap = mt9m111_cropcap, | 1018 | .cropcap = mt9m111_cropcap, |
1019 | .enum_mbus_fmt = mt9m111_enum_fmt, | ||
981 | }; | 1020 | }; |
982 | 1021 | ||
983 | static struct v4l2_subdev_ops mt9m111_subdev_ops = { | 1022 | static struct v4l2_subdev_ops mt9m111_subdev_ops = { |
@@ -1019,12 +1058,12 @@ static int mt9m111_probe(struct i2c_client *client, | |||
1019 | 1058 | ||
1020 | /* Second stage probe - when a capture adapter is there */ | 1059 | /* Second stage probe - when a capture adapter is there */ |
1021 | icd->ops = &mt9m111_ops; | 1060 | icd->ops = &mt9m111_ops; |
1022 | icd->y_skip_top = 0; | ||
1023 | 1061 | ||
1024 | mt9m111->rect.left = MT9M111_MIN_DARK_COLS; | 1062 | mt9m111->rect.left = MT9M111_MIN_DARK_COLS; |
1025 | mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; | 1063 | mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; |
1026 | mt9m111->rect.width = MT9M111_MAX_WIDTH; | 1064 | mt9m111->rect.width = MT9M111_MAX_WIDTH; |
1027 | mt9m111->rect.height = MT9M111_MAX_HEIGHT; | 1065 | mt9m111->rect.height = MT9M111_MAX_HEIGHT; |
1066 | mt9m111->fmt = &mt9m111_colour_fmts[0]; | ||
1028 | 1067 | ||
1029 | ret = mt9m111_video_probe(icd, client); | 1068 | ret = mt9m111_video_probe(icd, client); |
1030 | if (ret) { | 1069 | if (ret) { |
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 6966f644977..a9061bff79b 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -17,9 +17,11 @@ | |||
17 | #include <media/v4l2-chip-ident.h> | 17 | #include <media/v4l2-chip-ident.h> |
18 | #include <media/soc_camera.h> | 18 | #include <media/soc_camera.h> |
19 | 19 | ||
20 | /* mt9t031 i2c address 0x5d | 20 | /* |
21 | * mt9t031 i2c address 0x5d | ||
21 | * The platform has to define i2c_board_info and link to it from | 22 | * The platform has to define i2c_board_info and link to it from |
22 | * struct soc_camera_link */ | 23 | * struct soc_camera_link |
24 | */ | ||
23 | 25 | ||
24 | /* mt9t031 selected register addresses */ | 26 | /* mt9t031 selected register addresses */ |
25 | #define MT9T031_CHIP_VERSION 0x00 | 27 | #define MT9T031_CHIP_VERSION 0x00 |
@@ -58,15 +60,6 @@ | |||
58 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | \ | 60 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | \ |
59 | SOCAM_MASTER | SOCAM_DATAWIDTH_10) | 61 | SOCAM_MASTER | SOCAM_DATAWIDTH_10) |
60 | 62 | ||
61 | static const struct soc_camera_data_format mt9t031_colour_formats[] = { | ||
62 | { | ||
63 | .name = "Bayer (sRGB) 10 bit", | ||
64 | .depth = 10, | ||
65 | .fourcc = V4L2_PIX_FMT_SGRBG10, | ||
66 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
67 | } | ||
68 | }; | ||
69 | |||
70 | struct mt9t031 { | 63 | struct mt9t031 { |
71 | struct v4l2_subdev subdev; | 64 | struct v4l2_subdev subdev; |
72 | struct v4l2_rect rect; /* Sensor window */ | 65 | struct v4l2_rect rect; /* Sensor window */ |
@@ -74,6 +67,7 @@ struct mt9t031 { | |||
74 | u16 xskip; | 67 | u16 xskip; |
75 | u16 yskip; | 68 | u16 yskip; |
76 | unsigned int gain; | 69 | unsigned int gain; |
70 | unsigned short y_skip_top; /* Lines to skip at the top */ | ||
77 | unsigned int exposure; | 71 | unsigned int exposure; |
78 | unsigned char autoexposure; | 72 | unsigned char autoexposure; |
79 | }; | 73 | }; |
@@ -207,6 +201,71 @@ static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd) | |||
207 | return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); | 201 | return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); |
208 | } | 202 | } |
209 | 203 | ||
204 | enum { | ||
205 | MT9T031_CTRL_VFLIP, | ||
206 | MT9T031_CTRL_HFLIP, | ||
207 | MT9T031_CTRL_GAIN, | ||
208 | MT9T031_CTRL_EXPOSURE, | ||
209 | MT9T031_CTRL_EXPOSURE_AUTO, | ||
210 | }; | ||
211 | |||
212 | static const struct v4l2_queryctrl mt9t031_controls[] = { | ||
213 | [MT9T031_CTRL_VFLIP] = { | ||
214 | .id = V4L2_CID_VFLIP, | ||
215 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
216 | .name = "Flip Vertically", | ||
217 | .minimum = 0, | ||
218 | .maximum = 1, | ||
219 | .step = 1, | ||
220 | .default_value = 0, | ||
221 | }, | ||
222 | [MT9T031_CTRL_HFLIP] = { | ||
223 | .id = V4L2_CID_HFLIP, | ||
224 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
225 | .name = "Flip Horizontally", | ||
226 | .minimum = 0, | ||
227 | .maximum = 1, | ||
228 | .step = 1, | ||
229 | .default_value = 0, | ||
230 | }, | ||
231 | [MT9T031_CTRL_GAIN] = { | ||
232 | .id = V4L2_CID_GAIN, | ||
233 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
234 | .name = "Gain", | ||
235 | .minimum = 0, | ||
236 | .maximum = 127, | ||
237 | .step = 1, | ||
238 | .default_value = 64, | ||
239 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
240 | }, | ||
241 | [MT9T031_CTRL_EXPOSURE] = { | ||
242 | .id = V4L2_CID_EXPOSURE, | ||
243 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
244 | .name = "Exposure", | ||
245 | .minimum = 1, | ||
246 | .maximum = 255, | ||
247 | .step = 1, | ||
248 | .default_value = 255, | ||
249 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
250 | }, | ||
251 | [MT9T031_CTRL_EXPOSURE_AUTO] = { | ||
252 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
253 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
254 | .name = "Automatic Exposure", | ||
255 | .minimum = 0, | ||
256 | .maximum = 1, | ||
257 | .step = 1, | ||
258 | .default_value = 1, | ||
259 | } | ||
260 | }; | ||
261 | |||
262 | static struct soc_camera_ops mt9t031_ops = { | ||
263 | .set_bus_param = mt9t031_set_bus_param, | ||
264 | .query_bus_param = mt9t031_query_bus_param, | ||
265 | .controls = mt9t031_controls, | ||
266 | .num_controls = ARRAY_SIZE(mt9t031_controls), | ||
267 | }; | ||
268 | |||
210 | /* target must be _even_ */ | 269 | /* target must be _even_ */ |
211 | static u16 mt9t031_skip(s32 *source, s32 target, s32 max) | 270 | static u16 mt9t031_skip(s32 *source, s32 target, s32 max) |
212 | { | 271 | { |
@@ -226,10 +285,9 @@ static u16 mt9t031_skip(s32 *source, s32 target, s32 max) | |||
226 | } | 285 | } |
227 | 286 | ||
228 | /* rect is the sensor rectangle, the caller guarantees parameter validity */ | 287 | /* rect is the sensor rectangle, the caller guarantees parameter validity */ |
229 | static int mt9t031_set_params(struct soc_camera_device *icd, | 288 | static int mt9t031_set_params(struct i2c_client *client, |
230 | struct v4l2_rect *rect, u16 xskip, u16 yskip) | 289 | struct v4l2_rect *rect, u16 xskip, u16 yskip) |
231 | { | 290 | { |
232 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
233 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 291 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
234 | int ret; | 292 | int ret; |
235 | u16 xbin, ybin; | 293 | u16 xbin, ybin; |
@@ -291,8 +349,10 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
291 | dev_dbg(&client->dev, "new physical left %u, top %u\n", | 349 | dev_dbg(&client->dev, "new physical left %u, top %u\n", |
292 | rect->left, rect->top); | 350 | rect->left, rect->top); |
293 | 351 | ||
294 | /* The caller provides a supported format, as guaranteed by | 352 | /* |
295 | * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ | 353 | * The caller provides a supported format, as guaranteed by |
354 | * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() | ||
355 | */ | ||
296 | if (ret >= 0) | 356 | if (ret >= 0) |
297 | ret = reg_write(client, MT9T031_COLUMN_START, rect->left); | 357 | ret = reg_write(client, MT9T031_COLUMN_START, rect->left); |
298 | if (ret >= 0) | 358 | if (ret >= 0) |
@@ -301,15 +361,14 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
301 | ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1); | 361 | ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1); |
302 | if (ret >= 0) | 362 | if (ret >= 0) |
303 | ret = reg_write(client, MT9T031_WINDOW_HEIGHT, | 363 | ret = reg_write(client, MT9T031_WINDOW_HEIGHT, |
304 | rect->height + icd->y_skip_top - 1); | 364 | rect->height + mt9t031->y_skip_top - 1); |
305 | if (ret >= 0 && mt9t031->autoexposure) { | 365 | if (ret >= 0 && mt9t031->autoexposure) { |
306 | unsigned int total_h = rect->height + icd->y_skip_top + vblank; | 366 | unsigned int total_h = rect->height + mt9t031->y_skip_top + vblank; |
307 | ret = set_shutter(client, total_h); | 367 | ret = set_shutter(client, total_h); |
308 | if (ret >= 0) { | 368 | if (ret >= 0) { |
309 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 369 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
310 | const struct v4l2_queryctrl *qctrl = | 370 | const struct v4l2_queryctrl *qctrl = |
311 | soc_camera_find_qctrl(icd->ops, | 371 | &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; |
312 | V4L2_CID_EXPOSURE); | ||
313 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * | 372 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * |
314 | (qctrl->maximum - qctrl->minimum)) / | 373 | (qctrl->maximum - qctrl->minimum)) / |
315 | shutter_max + qctrl->minimum; | 374 | shutter_max + qctrl->minimum; |
@@ -334,7 +393,6 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
334 | struct v4l2_rect rect = a->c; | 393 | struct v4l2_rect rect = a->c; |
335 | struct i2c_client *client = sd->priv; | 394 | struct i2c_client *client = sd->priv; |
336 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 395 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
337 | struct soc_camera_device *icd = client->dev.platform_data; | ||
338 | 396 | ||
339 | rect.width = ALIGN(rect.width, 2); | 397 | rect.width = ALIGN(rect.width, 2); |
340 | rect.height = ALIGN(rect.height, 2); | 398 | rect.height = ALIGN(rect.height, 2); |
@@ -345,7 +403,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
345 | soc_camera_limit_side(&rect.top, &rect.height, | 403 | soc_camera_limit_side(&rect.top, &rect.height, |
346 | MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT); | 404 | MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT); |
347 | 405 | ||
348 | return mt9t031_set_params(icd, &rect, mt9t031->xskip, mt9t031->yskip); | 406 | return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip); |
349 | } | 407 | } |
350 | 408 | ||
351 | static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 409 | static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
@@ -373,27 +431,26 @@ static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
373 | return 0; | 431 | return 0; |
374 | } | 432 | } |
375 | 433 | ||
376 | static int mt9t031_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 434 | static int mt9t031_g_fmt(struct v4l2_subdev *sd, |
435 | struct v4l2_mbus_framefmt *mf) | ||
377 | { | 436 | { |
378 | struct i2c_client *client = sd->priv; | 437 | struct i2c_client *client = sd->priv; |
379 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 438 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
380 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
381 | 439 | ||
382 | pix->width = mt9t031->rect.width / mt9t031->xskip; | 440 | mf->width = mt9t031->rect.width / mt9t031->xskip; |
383 | pix->height = mt9t031->rect.height / mt9t031->yskip; | 441 | mf->height = mt9t031->rect.height / mt9t031->yskip; |
384 | pix->pixelformat = V4L2_PIX_FMT_SGRBG10; | 442 | mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; |
385 | pix->field = V4L2_FIELD_NONE; | 443 | mf->colorspace = V4L2_COLORSPACE_SRGB; |
386 | pix->colorspace = V4L2_COLORSPACE_SRGB; | 444 | mf->field = V4L2_FIELD_NONE; |
387 | 445 | ||
388 | return 0; | 446 | return 0; |
389 | } | 447 | } |
390 | 448 | ||
391 | static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 449 | static int mt9t031_s_fmt(struct v4l2_subdev *sd, |
450 | struct v4l2_mbus_framefmt *mf) | ||
392 | { | 451 | { |
393 | struct i2c_client *client = sd->priv; | 452 | struct i2c_client *client = sd->priv; |
394 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 453 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
395 | struct soc_camera_device *icd = client->dev.platform_data; | ||
396 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
397 | u16 xskip, yskip; | 454 | u16 xskip, yskip; |
398 | struct v4l2_rect rect = mt9t031->rect; | 455 | struct v4l2_rect rect = mt9t031->rect; |
399 | 456 | ||
@@ -401,24 +458,29 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |||
401 | * try_fmt has put width and height within limits. | 458 | * try_fmt has put width and height within limits. |
402 | * S_FMT: use binning and skipping for scaling | 459 | * S_FMT: use binning and skipping for scaling |
403 | */ | 460 | */ |
404 | xskip = mt9t031_skip(&rect.width, pix->width, MT9T031_MAX_WIDTH); | 461 | xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH); |
405 | yskip = mt9t031_skip(&rect.height, pix->height, MT9T031_MAX_HEIGHT); | 462 | yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT); |
463 | |||
464 | mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; | ||
465 | mf->colorspace = V4L2_COLORSPACE_SRGB; | ||
406 | 466 | ||
407 | /* mt9t031_set_params() doesn't change width and height */ | 467 | /* mt9t031_set_params() doesn't change width and height */ |
408 | return mt9t031_set_params(icd, &rect, xskip, yskip); | 468 | return mt9t031_set_params(client, &rect, xskip, yskip); |
409 | } | 469 | } |
410 | 470 | ||
411 | /* | 471 | /* |
412 | * If a user window larger than sensor window is requested, we'll increase the | 472 | * If a user window larger than sensor window is requested, we'll increase the |
413 | * sensor window. | 473 | * sensor window. |
414 | */ | 474 | */ |
415 | static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 475 | static int mt9t031_try_fmt(struct v4l2_subdev *sd, |
476 | struct v4l2_mbus_framefmt *mf) | ||
416 | { | 477 | { |
417 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
418 | |||
419 | v4l_bound_align_image( | 478 | v4l_bound_align_image( |
420 | &pix->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, | 479 | &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, |
421 | &pix->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); | 480 | &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); |
481 | |||
482 | mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; | ||
483 | mf->colorspace = V4L2_COLORSPACE_SRGB; | ||
422 | 484 | ||
423 | return 0; | 485 | return 0; |
424 | } | 486 | } |
@@ -479,59 +541,6 @@ static int mt9t031_s_register(struct v4l2_subdev *sd, | |||
479 | } | 541 | } |
480 | #endif | 542 | #endif |
481 | 543 | ||
482 | static const struct v4l2_queryctrl mt9t031_controls[] = { | ||
483 | { | ||
484 | .id = V4L2_CID_VFLIP, | ||
485 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
486 | .name = "Flip Vertically", | ||
487 | .minimum = 0, | ||
488 | .maximum = 1, | ||
489 | .step = 1, | ||
490 | .default_value = 0, | ||
491 | }, { | ||
492 | .id = V4L2_CID_HFLIP, | ||
493 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
494 | .name = "Flip Horizontally", | ||
495 | .minimum = 0, | ||
496 | .maximum = 1, | ||
497 | .step = 1, | ||
498 | .default_value = 0, | ||
499 | }, { | ||
500 | .id = V4L2_CID_GAIN, | ||
501 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
502 | .name = "Gain", | ||
503 | .minimum = 0, | ||
504 | .maximum = 127, | ||
505 | .step = 1, | ||
506 | .default_value = 64, | ||
507 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
508 | }, { | ||
509 | .id = V4L2_CID_EXPOSURE, | ||
510 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
511 | .name = "Exposure", | ||
512 | .minimum = 1, | ||
513 | .maximum = 255, | ||
514 | .step = 1, | ||
515 | .default_value = 255, | ||
516 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
517 | }, { | ||
518 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
519 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
520 | .name = "Automatic Exposure", | ||
521 | .minimum = 0, | ||
522 | .maximum = 1, | ||
523 | .step = 1, | ||
524 | .default_value = 1, | ||
525 | } | ||
526 | }; | ||
527 | |||
528 | static struct soc_camera_ops mt9t031_ops = { | ||
529 | .set_bus_param = mt9t031_set_bus_param, | ||
530 | .query_bus_param = mt9t031_query_bus_param, | ||
531 | .controls = mt9t031_controls, | ||
532 | .num_controls = ARRAY_SIZE(mt9t031_controls), | ||
533 | }; | ||
534 | |||
535 | static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 544 | static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
536 | { | 545 | { |
537 | struct i2c_client *client = sd->priv; | 546 | struct i2c_client *client = sd->priv; |
@@ -568,15 +577,9 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
568 | { | 577 | { |
569 | struct i2c_client *client = sd->priv; | 578 | struct i2c_client *client = sd->priv; |
570 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 579 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
571 | struct soc_camera_device *icd = client->dev.platform_data; | ||
572 | const struct v4l2_queryctrl *qctrl; | 580 | const struct v4l2_queryctrl *qctrl; |
573 | int data; | 581 | int data; |
574 | 582 | ||
575 | qctrl = soc_camera_find_qctrl(&mt9t031_ops, ctrl->id); | ||
576 | |||
577 | if (!qctrl) | ||
578 | return -EINVAL; | ||
579 | |||
580 | switch (ctrl->id) { | 583 | switch (ctrl->id) { |
581 | case V4L2_CID_VFLIP: | 584 | case V4L2_CID_VFLIP: |
582 | if (ctrl->value) | 585 | if (ctrl->value) |
@@ -595,6 +598,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
595 | return -EIO; | 598 | return -EIO; |
596 | break; | 599 | break; |
597 | case V4L2_CID_GAIN: | 600 | case V4L2_CID_GAIN: |
601 | qctrl = &mt9t031_controls[MT9T031_CTRL_GAIN]; | ||
598 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) | 602 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) |
599 | return -EINVAL; | 603 | return -EINVAL; |
600 | /* See Datasheet Table 7, Gain settings. */ | 604 | /* See Datasheet Table 7, Gain settings. */ |
@@ -634,6 +638,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
634 | mt9t031->gain = ctrl->value; | 638 | mt9t031->gain = ctrl->value; |
635 | break; | 639 | break; |
636 | case V4L2_CID_EXPOSURE: | 640 | case V4L2_CID_EXPOSURE: |
641 | qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; | ||
637 | /* mt9t031 has maximum == default */ | 642 | /* mt9t031 has maximum == default */ |
638 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) | 643 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) |
639 | return -EINVAL; | 644 | return -EINVAL; |
@@ -657,11 +662,11 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
657 | const u16 vblank = MT9T031_VERTICAL_BLANK; | 662 | const u16 vblank = MT9T031_VERTICAL_BLANK; |
658 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 663 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
659 | unsigned int total_h = mt9t031->rect.height + | 664 | unsigned int total_h = mt9t031->rect.height + |
660 | icd->y_skip_top + vblank; | 665 | mt9t031->y_skip_top + vblank; |
661 | 666 | ||
662 | if (set_shutter(client, total_h) < 0) | 667 | if (set_shutter(client, total_h) < 0) |
663 | return -EIO; | 668 | return -EIO; |
664 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | 669 | qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; |
665 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * | 670 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * |
666 | (qctrl->maximum - qctrl->minimum)) / | 671 | (qctrl->maximum - qctrl->minimum)) / |
667 | shutter_max + qctrl->minimum; | 672 | shutter_max + qctrl->minimum; |
@@ -669,15 +674,18 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
669 | } else | 674 | } else |
670 | mt9t031->autoexposure = 0; | 675 | mt9t031->autoexposure = 0; |
671 | break; | 676 | break; |
677 | default: | ||
678 | return -EINVAL; | ||
672 | } | 679 | } |
673 | return 0; | 680 | return 0; |
674 | } | 681 | } |
675 | 682 | ||
676 | /* Interface active, can use i2c. If it fails, it can indeed mean, that | 683 | /* |
677 | * this wasn't our capture interface, so, we wait for the right one */ | 684 | * Interface active, can use i2c. If it fails, it can indeed mean, that |
685 | * this wasn't our capture interface, so, we wait for the right one | ||
686 | */ | ||
678 | static int mt9t031_video_probe(struct i2c_client *client) | 687 | static int mt9t031_video_probe(struct i2c_client *client) |
679 | { | 688 | { |
680 | struct soc_camera_device *icd = client->dev.platform_data; | ||
681 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 689 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
682 | s32 data; | 690 | s32 data; |
683 | int ret; | 691 | int ret; |
@@ -692,8 +700,6 @@ static int mt9t031_video_probe(struct i2c_client *client) | |||
692 | switch (data) { | 700 | switch (data) { |
693 | case 0x1621: | 701 | case 0x1621: |
694 | mt9t031->model = V4L2_IDENT_MT9T031; | 702 | mt9t031->model = V4L2_IDENT_MT9T031; |
695 | icd->formats = mt9t031_colour_formats; | ||
696 | icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats); | ||
697 | break; | 703 | break; |
698 | default: | 704 | default: |
699 | dev_err(&client->dev, | 705 | dev_err(&client->dev, |
@@ -714,6 +720,16 @@ static int mt9t031_video_probe(struct i2c_client *client) | |||
714 | return ret; | 720 | return ret; |
715 | } | 721 | } |
716 | 722 | ||
723 | static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) | ||
724 | { | ||
725 | struct i2c_client *client = sd->priv; | ||
726 | struct mt9t031 *mt9t031 = to_mt9t031(client); | ||
727 | |||
728 | *lines = mt9t031->y_skip_top; | ||
729 | |||
730 | return 0; | ||
731 | } | ||
732 | |||
717 | static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { | 733 | static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { |
718 | .g_ctrl = mt9t031_g_ctrl, | 734 | .g_ctrl = mt9t031_g_ctrl, |
719 | .s_ctrl = mt9t031_s_ctrl, | 735 | .s_ctrl = mt9t031_s_ctrl, |
@@ -724,19 +740,35 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { | |||
724 | #endif | 740 | #endif |
725 | }; | 741 | }; |
726 | 742 | ||
743 | static int mt9t031_enum_fmt(struct v4l2_subdev *sd, int index, | ||
744 | enum v4l2_mbus_pixelcode *code) | ||
745 | { | ||
746 | if (index) | ||
747 | return -EINVAL; | ||
748 | |||
749 | *code = V4L2_MBUS_FMT_SBGGR10_1X10; | ||
750 | return 0; | ||
751 | } | ||
752 | |||
727 | static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { | 753 | static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { |
728 | .s_stream = mt9t031_s_stream, | 754 | .s_stream = mt9t031_s_stream, |
729 | .s_fmt = mt9t031_s_fmt, | 755 | .s_mbus_fmt = mt9t031_s_fmt, |
730 | .g_fmt = mt9t031_g_fmt, | 756 | .g_mbus_fmt = mt9t031_g_fmt, |
731 | .try_fmt = mt9t031_try_fmt, | 757 | .try_mbus_fmt = mt9t031_try_fmt, |
732 | .s_crop = mt9t031_s_crop, | 758 | .s_crop = mt9t031_s_crop, |
733 | .g_crop = mt9t031_g_crop, | 759 | .g_crop = mt9t031_g_crop, |
734 | .cropcap = mt9t031_cropcap, | 760 | .cropcap = mt9t031_cropcap, |
761 | .enum_mbus_fmt = mt9t031_enum_fmt, | ||
762 | }; | ||
763 | |||
764 | static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = { | ||
765 | .g_skip_top_lines = mt9t031_g_skip_top_lines, | ||
735 | }; | 766 | }; |
736 | 767 | ||
737 | static struct v4l2_subdev_ops mt9t031_subdev_ops = { | 768 | static struct v4l2_subdev_ops mt9t031_subdev_ops = { |
738 | .core = &mt9t031_subdev_core_ops, | 769 | .core = &mt9t031_subdev_core_ops, |
739 | .video = &mt9t031_subdev_video_ops, | 770 | .video = &mt9t031_subdev_video_ops, |
771 | .sensor = &mt9t031_subdev_sensor_ops, | ||
740 | }; | 772 | }; |
741 | 773 | ||
742 | static int mt9t031_probe(struct i2c_client *client, | 774 | static int mt9t031_probe(struct i2c_client *client, |
@@ -745,18 +777,16 @@ static int mt9t031_probe(struct i2c_client *client, | |||
745 | struct mt9t031 *mt9t031; | 777 | struct mt9t031 *mt9t031; |
746 | struct soc_camera_device *icd = client->dev.platform_data; | 778 | struct soc_camera_device *icd = client->dev.platform_data; |
747 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 779 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
748 | struct soc_camera_link *icl; | ||
749 | int ret; | 780 | int ret; |
750 | 781 | ||
751 | if (!icd) { | 782 | if (icd) { |
752 | dev_err(&client->dev, "MT9T031: missing soc-camera data!\n"); | 783 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
753 | return -EINVAL; | 784 | if (!icl) { |
754 | } | 785 | dev_err(&client->dev, "MT9T031 driver needs platform data\n"); |
786 | return -EINVAL; | ||
787 | } | ||
755 | 788 | ||
756 | icl = to_soc_camera_link(icd); | 789 | icd->ops = &mt9t031_ops; |
757 | if (!icl) { | ||
758 | dev_err(&client->dev, "MT9T031 driver needs platform data\n"); | ||
759 | return -EINVAL; | ||
760 | } | 790 | } |
761 | 791 | ||
762 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { | 792 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { |
@@ -771,17 +801,16 @@ static int mt9t031_probe(struct i2c_client *client, | |||
771 | 801 | ||
772 | v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops); | 802 | v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops); |
773 | 803 | ||
774 | /* Second stage probe - when a capture adapter is there */ | 804 | mt9t031->y_skip_top = 0; |
775 | icd->ops = &mt9t031_ops; | ||
776 | icd->y_skip_top = 0; | ||
777 | |||
778 | mt9t031->rect.left = MT9T031_COLUMN_SKIP; | 805 | mt9t031->rect.left = MT9T031_COLUMN_SKIP; |
779 | mt9t031->rect.top = MT9T031_ROW_SKIP; | 806 | mt9t031->rect.top = MT9T031_ROW_SKIP; |
780 | mt9t031->rect.width = MT9T031_MAX_WIDTH; | 807 | mt9t031->rect.width = MT9T031_MAX_WIDTH; |
781 | mt9t031->rect.height = MT9T031_MAX_HEIGHT; | 808 | mt9t031->rect.height = MT9T031_MAX_HEIGHT; |
782 | 809 | ||
783 | /* Simulated autoexposure. If enabled, we calculate shutter width | 810 | /* |
784 | * ourselves in the driver based on vertical blanking and frame width */ | 811 | * Simulated autoexposure. If enabled, we calculate shutter width |
812 | * ourselves in the driver based on vertical blanking and frame width | ||
813 | */ | ||
785 | mt9t031->autoexposure = 1; | 814 | mt9t031->autoexposure = 1; |
786 | 815 | ||
787 | mt9t031->xskip = 1; | 816 | mt9t031->xskip = 1; |
@@ -794,7 +823,8 @@ static int mt9t031_probe(struct i2c_client *client, | |||
794 | mt9t031_disable(client); | 823 | mt9t031_disable(client); |
795 | 824 | ||
796 | if (ret) { | 825 | if (ret) { |
797 | icd->ops = NULL; | 826 | if (icd) |
827 | icd->ops = NULL; | ||
798 | i2c_set_clientdata(client, NULL); | 828 | i2c_set_clientdata(client, NULL); |
799 | kfree(mt9t031); | 829 | kfree(mt9t031); |
800 | } | 830 | } |
@@ -807,7 +837,8 @@ static int mt9t031_remove(struct i2c_client *client) | |||
807 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 837 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
808 | struct soc_camera_device *icd = client->dev.platform_data; | 838 | struct soc_camera_device *icd = client->dev.platform_data; |
809 | 839 | ||
810 | icd->ops = NULL; | 840 | if (icd) |
841 | icd->ops = NULL; | ||
811 | i2c_set_clientdata(client, NULL); | 842 | i2c_set_clientdata(client, NULL); |
812 | client->driver = NULL; | 843 | client->driver = NULL; |
813 | kfree(mt9t031); | 844 | kfree(mt9t031); |
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c new file mode 100644 index 00000000000..fc4dd604572 --- /dev/null +++ b/drivers/media/video/mt9t112.c | |||
@@ -0,0 +1,1177 @@ | |||
1 | /* | ||
2 | * mt9t112 Camera Driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Renesas Solutions Corp. | ||
5 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
6 | * | ||
7 | * Based on ov772x driver, mt9m111 driver, | ||
8 | * | ||
9 | * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
10 | * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr> | ||
11 | * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net> | ||
12 | * Copyright (C) 2008 Magnus Damm | ||
13 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License version 2 as | ||
17 | * published by the Free Software Foundation. | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/videodev2.h> | ||
26 | |||
27 | #include <media/mt9t112.h> | ||
28 | #include <media/soc_camera.h> | ||
29 | #include <media/soc_mediabus.h> | ||
30 | #include <media/v4l2-chip-ident.h> | ||
31 | #include <media/v4l2-common.h> | ||
32 | |||
33 | /* you can check PLL/clock info */ | ||
34 | /* #define EXT_CLOCK 24000000 */ | ||
35 | |||
36 | /************************************************************************ | ||
37 | |||
38 | |||
39 | macro | ||
40 | |||
41 | |||
42 | ************************************************************************/ | ||
43 | /* | ||
44 | * frame size | ||
45 | */ | ||
46 | #define MAX_WIDTH 2048 | ||
47 | #define MAX_HEIGHT 1536 | ||
48 | |||
49 | #define VGA_WIDTH 640 | ||
50 | #define VGA_HEIGHT 480 | ||
51 | |||
52 | /* | ||
53 | * macro of read/write | ||
54 | */ | ||
55 | #define ECHECKER(ret, x) \ | ||
56 | do { \ | ||
57 | (ret) = (x); \ | ||
58 | if ((ret) < 0) \ | ||
59 | return (ret); \ | ||
60 | } while (0) | ||
61 | |||
62 | #define mt9t112_reg_write(ret, client, a, b) \ | ||
63 | ECHECKER(ret, __mt9t112_reg_write(client, a, b)) | ||
64 | #define mt9t112_mcu_write(ret, client, a, b) \ | ||
65 | ECHECKER(ret, __mt9t112_mcu_write(client, a, b)) | ||
66 | |||
67 | #define mt9t112_reg_mask_set(ret, client, a, b, c) \ | ||
68 | ECHECKER(ret, __mt9t112_reg_mask_set(client, a, b, c)) | ||
69 | #define mt9t112_mcu_mask_set(ret, client, a, b, c) \ | ||
70 | ECHECKER(ret, __mt9t112_mcu_mask_set(client, a, b, c)) | ||
71 | |||
72 | #define mt9t112_reg_read(ret, client, a) \ | ||
73 | ECHECKER(ret, __mt9t112_reg_read(client, a)) | ||
74 | |||
75 | /* | ||
76 | * Logical address | ||
77 | */ | ||
78 | #define _VAR(id, offset, base) (base | (id & 0x1f) << 10 | (offset & 0x3ff)) | ||
79 | #define VAR(id, offset) _VAR(id, offset, 0x0000) | ||
80 | #define VAR8(id, offset) _VAR(id, offset, 0x8000) | ||
81 | |||
82 | /************************************************************************ | ||
83 | |||
84 | |||
85 | struct | ||
86 | |||
87 | |||
88 | ************************************************************************/ | ||
89 | struct mt9t112_frame_size { | ||
90 | u16 width; | ||
91 | u16 height; | ||
92 | }; | ||
93 | |||
94 | struct mt9t112_format { | ||
95 | enum v4l2_mbus_pixelcode code; | ||
96 | enum v4l2_colorspace colorspace; | ||
97 | u16 fmt; | ||
98 | u16 order; | ||
99 | }; | ||
100 | |||
101 | struct mt9t112_priv { | ||
102 | struct v4l2_subdev subdev; | ||
103 | struct mt9t112_camera_info *info; | ||
104 | struct i2c_client *client; | ||
105 | struct soc_camera_device icd; | ||
106 | struct mt9t112_frame_size frame; | ||
107 | const struct mt9t112_format *format; | ||
108 | int model; | ||
109 | u32 flags; | ||
110 | /* for flags */ | ||
111 | #define INIT_DONE (1<<0) | ||
112 | }; | ||
113 | |||
114 | /************************************************************************ | ||
115 | |||
116 | |||
117 | supported format | ||
118 | |||
119 | |||
120 | ************************************************************************/ | ||
121 | |||
122 | static const struct mt9t112_format mt9t112_cfmts[] = { | ||
123 | { | ||
124 | .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, | ||
125 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
126 | .fmt = 1, | ||
127 | .order = 0, | ||
128 | }, { | ||
129 | .code = V4L2_MBUS_FMT_YVYU8_2X8_BE, | ||
130 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
131 | .fmt = 1, | ||
132 | .order = 1, | ||
133 | }, { | ||
134 | .code = V4L2_MBUS_FMT_YUYV8_2X8_LE, | ||
135 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
136 | .fmt = 1, | ||
137 | .order = 2, | ||
138 | }, { | ||
139 | .code = V4L2_MBUS_FMT_YVYU8_2X8_LE, | ||
140 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
141 | .fmt = 1, | ||
142 | .order = 3, | ||
143 | }, { | ||
144 | .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, | ||
145 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
146 | .fmt = 8, | ||
147 | .order = 2, | ||
148 | }, { | ||
149 | .code = V4L2_MBUS_FMT_RGB565_2X8_LE, | ||
150 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
151 | .fmt = 4, | ||
152 | .order = 2, | ||
153 | }, | ||
154 | }; | ||
155 | |||
156 | /************************************************************************ | ||
157 | |||
158 | |||
159 | general function | ||
160 | |||
161 | |||
162 | ************************************************************************/ | ||
163 | static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client) | ||
164 | { | ||
165 | return container_of(i2c_get_clientdata(client), | ||
166 | struct mt9t112_priv, | ||
167 | subdev); | ||
168 | } | ||
169 | |||
170 | static int __mt9t112_reg_read(const struct i2c_client *client, u16 command) | ||
171 | { | ||
172 | struct i2c_msg msg[2]; | ||
173 | u8 buf[2]; | ||
174 | int ret; | ||
175 | |||
176 | command = swab16(command); | ||
177 | |||
178 | msg[0].addr = client->addr; | ||
179 | msg[0].flags = 0; | ||
180 | msg[0].len = 2; | ||
181 | msg[0].buf = (u8 *)&command; | ||
182 | |||
183 | msg[1].addr = client->addr; | ||
184 | msg[1].flags = I2C_M_RD; | ||
185 | msg[1].len = 2; | ||
186 | msg[1].buf = buf; | ||
187 | |||
188 | /* | ||
189 | * if return value of this function is < 0, | ||
190 | * it mean error. | ||
191 | * else, under 16bit is valid data. | ||
192 | */ | ||
193 | ret = i2c_transfer(client->adapter, msg, 2); | ||
194 | if (ret < 0) | ||
195 | return ret; | ||
196 | |||
197 | memcpy(&ret, buf, 2); | ||
198 | return swab16(ret); | ||
199 | } | ||
200 | |||
201 | static int __mt9t112_reg_write(const struct i2c_client *client, | ||
202 | u16 command, u16 data) | ||
203 | { | ||
204 | struct i2c_msg msg; | ||
205 | u8 buf[4]; | ||
206 | int ret; | ||
207 | |||
208 | command = swab16(command); | ||
209 | data = swab16(data); | ||
210 | |||
211 | memcpy(buf + 0, &command, 2); | ||
212 | memcpy(buf + 2, &data, 2); | ||
213 | |||
214 | msg.addr = client->addr; | ||
215 | msg.flags = 0; | ||
216 | msg.len = 4; | ||
217 | msg.buf = buf; | ||
218 | |||
219 | /* | ||
220 | * i2c_transfer return message length, | ||
221 | * but this function should return 0 if correct case | ||
222 | */ | ||
223 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
224 | if (ret >= 0) | ||
225 | ret = 0; | ||
226 | |||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static int __mt9t112_reg_mask_set(const struct i2c_client *client, | ||
231 | u16 command, | ||
232 | u16 mask, | ||
233 | u16 set) | ||
234 | { | ||
235 | int val = __mt9t112_reg_read(client, command); | ||
236 | if (val < 0) | ||
237 | return val; | ||
238 | |||
239 | val &= ~mask; | ||
240 | val |= set & mask; | ||
241 | |||
242 | return __mt9t112_reg_write(client, command, val); | ||
243 | } | ||
244 | |||
245 | /* mcu access */ | ||
246 | static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command) | ||
247 | { | ||
248 | int ret; | ||
249 | |||
250 | ret = __mt9t112_reg_write(client, 0x098E, command); | ||
251 | if (ret < 0) | ||
252 | return ret; | ||
253 | |||
254 | return __mt9t112_reg_read(client, 0x0990); | ||
255 | } | ||
256 | |||
257 | static int __mt9t112_mcu_write(const struct i2c_client *client, | ||
258 | u16 command, u16 data) | ||
259 | { | ||
260 | int ret; | ||
261 | |||
262 | ret = __mt9t112_reg_write(client, 0x098E, command); | ||
263 | if (ret < 0) | ||
264 | return ret; | ||
265 | |||
266 | return __mt9t112_reg_write(client, 0x0990, data); | ||
267 | } | ||
268 | |||
269 | static int __mt9t112_mcu_mask_set(const struct i2c_client *client, | ||
270 | u16 command, | ||
271 | u16 mask, | ||
272 | u16 set) | ||
273 | { | ||
274 | int val = __mt9t112_mcu_read(client, command); | ||
275 | if (val < 0) | ||
276 | return val; | ||
277 | |||
278 | val &= ~mask; | ||
279 | val |= set & mask; | ||
280 | |||
281 | return __mt9t112_mcu_write(client, command, val); | ||
282 | } | ||
283 | |||
284 | static int mt9t112_reset(const struct i2c_client *client) | ||
285 | { | ||
286 | int ret; | ||
287 | |||
288 | mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001); | ||
289 | msleep(1); | ||
290 | mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000); | ||
291 | |||
292 | return ret; | ||
293 | } | ||
294 | |||
295 | #ifndef EXT_CLOCK | ||
296 | #define CLOCK_INFO(a, b) | ||
297 | #else | ||
298 | #define CLOCK_INFO(a, b) mt9t112_clock_info(a, b) | ||
299 | static int mt9t112_clock_info(const struct i2c_client *client, u32 ext) | ||
300 | { | ||
301 | int m, n, p1, p2, p3, p4, p5, p6, p7; | ||
302 | u32 vco, clk; | ||
303 | char *enable; | ||
304 | |||
305 | ext /= 1000; /* kbyte order */ | ||
306 | |||
307 | mt9t112_reg_read(n, client, 0x0012); | ||
308 | p1 = n & 0x000f; | ||
309 | n = n >> 4; | ||
310 | p2 = n & 0x000f; | ||
311 | n = n >> 4; | ||
312 | p3 = n & 0x000f; | ||
313 | |||
314 | mt9t112_reg_read(n, client, 0x002a); | ||
315 | p4 = n & 0x000f; | ||
316 | n = n >> 4; | ||
317 | p5 = n & 0x000f; | ||
318 | n = n >> 4; | ||
319 | p6 = n & 0x000f; | ||
320 | |||
321 | mt9t112_reg_read(n, client, 0x002c); | ||
322 | p7 = n & 0x000f; | ||
323 | |||
324 | mt9t112_reg_read(n, client, 0x0010); | ||
325 | m = n & 0x00ff; | ||
326 | n = (n >> 8) & 0x003f; | ||
327 | |||
328 | enable = ((6000 > ext) || (54000 < ext)) ? "X" : ""; | ||
329 | dev_info(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); | ||
330 | |||
331 | vco = 2 * m * ext / (n+1); | ||
332 | enable = ((384000 > vco) || (768000 < vco)) ? "X" : ""; | ||
333 | dev_info(&client->dev, "VCO : %10u K %s\n", vco, enable); | ||
334 | |||
335 | clk = vco / (p1+1) / (p2+1); | ||
336 | enable = (96000 < clk) ? "X" : ""; | ||
337 | dev_info(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); | ||
338 | |||
339 | clk = vco / (p3+1); | ||
340 | enable = (768000 < clk) ? "X" : ""; | ||
341 | dev_info(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); | ||
342 | |||
343 | clk = vco / (p6+1); | ||
344 | enable = (96000 < clk) ? "X" : ""; | ||
345 | dev_info(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); | ||
346 | |||
347 | clk = vco / (p5+1); | ||
348 | enable = (54000 < clk) ? "X" : ""; | ||
349 | dev_info(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); | ||
350 | |||
351 | clk = vco / (p4+1); | ||
352 | enable = (70000 < clk) ? "X" : ""; | ||
353 | dev_info(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); | ||
354 | |||
355 | clk = vco / (p7+1); | ||
356 | dev_info(&client->dev, "External sensor : %10u K\n", clk); | ||
357 | |||
358 | clk = ext / (n+1); | ||
359 | enable = ((2000 > clk) || (24000 < clk)) ? "X" : ""; | ||
360 | dev_info(&client->dev, "PFD : %10u K %s\n", clk, enable); | ||
361 | |||
362 | return 0; | ||
363 | } | ||
364 | #endif | ||
365 | |||
366 | static void mt9t112_frame_check(u32 *width, u32 *height) | ||
367 | { | ||
368 | if (*width > MAX_WIDTH) | ||
369 | *width = MAX_WIDTH; | ||
370 | |||
371 | if (*height > MAX_HEIGHT) | ||
372 | *height = MAX_HEIGHT; | ||
373 | } | ||
374 | |||
375 | static int mt9t112_set_a_frame_size(const struct i2c_client *client, | ||
376 | u16 width, | ||
377 | u16 height) | ||
378 | { | ||
379 | int ret; | ||
380 | u16 wstart = (MAX_WIDTH - width) / 2; | ||
381 | u16 hstart = (MAX_HEIGHT - height) / 2; | ||
382 | |||
383 | /* (Context A) Image Width/Height */ | ||
384 | mt9t112_mcu_write(ret, client, VAR(26, 0), width); | ||
385 | mt9t112_mcu_write(ret, client, VAR(26, 2), height); | ||
386 | |||
387 | /* (Context A) Output Width/Height */ | ||
388 | mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width); | ||
389 | mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height); | ||
390 | |||
391 | /* (Context A) Start Row/Column */ | ||
392 | mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart); | ||
393 | mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart); | ||
394 | |||
395 | /* (Context A) End Row/Column */ | ||
396 | mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart); | ||
397 | mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width + wstart); | ||
398 | |||
399 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); | ||
400 | |||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | static int mt9t112_set_pll_dividers(const struct i2c_client *client, | ||
405 | u8 m, u8 n, | ||
406 | u8 p1, u8 p2, u8 p3, | ||
407 | u8 p4, u8 p5, u8 p6, | ||
408 | u8 p7) | ||
409 | { | ||
410 | int ret; | ||
411 | u16 val; | ||
412 | |||
413 | /* N/M */ | ||
414 | val = (n << 8) | | ||
415 | (m << 0); | ||
416 | mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val); | ||
417 | |||
418 | /* P1/P2/P3 */ | ||
419 | val = ((p3 & 0x0F) << 8) | | ||
420 | ((p2 & 0x0F) << 4) | | ||
421 | ((p1 & 0x0F) << 0); | ||
422 | mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val); | ||
423 | |||
424 | /* P4/P5/P6 */ | ||
425 | val = (0x7 << 12) | | ||
426 | ((p6 & 0x0F) << 8) | | ||
427 | ((p5 & 0x0F) << 4) | | ||
428 | ((p4 & 0x0F) << 0); | ||
429 | mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val); | ||
430 | |||
431 | /* P7 */ | ||
432 | val = (0x1 << 12) | | ||
433 | ((p7 & 0x0F) << 0); | ||
434 | mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val); | ||
435 | |||
436 | return ret; | ||
437 | } | ||
438 | |||
439 | static int mt9t112_init_pll(const struct i2c_client *client) | ||
440 | { | ||
441 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
442 | int data, i, ret; | ||
443 | |||
444 | mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001); | ||
445 | |||
446 | /* PLL control: BYPASS PLL = 8517 */ | ||
447 | mt9t112_reg_write(ret, client, 0x0014, 0x2145); | ||
448 | |||
449 | /* Replace these registers when new timing parameters are generated */ | ||
450 | mt9t112_set_pll_dividers(client, | ||
451 | priv->info->divider.m, | ||
452 | priv->info->divider.n, | ||
453 | priv->info->divider.p1, | ||
454 | priv->info->divider.p2, | ||
455 | priv->info->divider.p3, | ||
456 | priv->info->divider.p4, | ||
457 | priv->info->divider.p5, | ||
458 | priv->info->divider.p6, | ||
459 | priv->info->divider.p7); | ||
460 | |||
461 | /* | ||
462 | * TEST_BYPASS on | ||
463 | * PLL_ENABLE on | ||
464 | * SEL_LOCK_DET on | ||
465 | * TEST_BYPASS off | ||
466 | */ | ||
467 | mt9t112_reg_write(ret, client, 0x0014, 0x2525); | ||
468 | mt9t112_reg_write(ret, client, 0x0014, 0x2527); | ||
469 | mt9t112_reg_write(ret, client, 0x0014, 0x3427); | ||
470 | mt9t112_reg_write(ret, client, 0x0014, 0x3027); | ||
471 | |||
472 | mdelay(10); | ||
473 | |||
474 | /* | ||
475 | * PLL_BYPASS off | ||
476 | * Reference clock count | ||
477 | * I2C Master Clock Divider | ||
478 | */ | ||
479 | mt9t112_reg_write(ret, client, 0x0014, 0x3046); | ||
480 | mt9t112_reg_write(ret, client, 0x0022, 0x0190); | ||
481 | mt9t112_reg_write(ret, client, 0x3B84, 0x0212); | ||
482 | |||
483 | /* External sensor clock is PLL bypass */ | ||
484 | mt9t112_reg_write(ret, client, 0x002E, 0x0500); | ||
485 | |||
486 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002); | ||
487 | mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004); | ||
488 | |||
489 | /* MCU disabled */ | ||
490 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004); | ||
491 | |||
492 | /* out of standby */ | ||
493 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0); | ||
494 | |||
495 | mdelay(50); | ||
496 | |||
497 | /* | ||
498 | * Standby Workaround | ||
499 | * Disable Secondary I2C Pads | ||
500 | */ | ||
501 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
502 | mdelay(1); | ||
503 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
504 | mdelay(1); | ||
505 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
506 | mdelay(1); | ||
507 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
508 | mdelay(1); | ||
509 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
510 | mdelay(1); | ||
511 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
512 | mdelay(1); | ||
513 | |||
514 | /* poll to verify out of standby. Must Poll this bit */ | ||
515 | for (i = 0; i < 100; i++) { | ||
516 | mt9t112_reg_read(data, client, 0x0018); | ||
517 | if (0x4000 & data) | ||
518 | break; | ||
519 | |||
520 | mdelay(10); | ||
521 | } | ||
522 | |||
523 | return ret; | ||
524 | } | ||
525 | |||
526 | static int mt9t112_init_setting(const struct i2c_client *client) | ||
527 | { | ||
528 | |||
529 | int ret; | ||
530 | |||
531 | /* Adaptive Output Clock (A) */ | ||
532 | mt9t112_mcu_mask_set(ret, client, VAR(26, 160), 0x0040, 0x0000); | ||
533 | |||
534 | /* Read Mode (A) */ | ||
535 | mt9t112_mcu_write(ret, client, VAR(18, 12), 0x0024); | ||
536 | |||
537 | /* Fine Correction (A) */ | ||
538 | mt9t112_mcu_write(ret, client, VAR(18, 15), 0x00CC); | ||
539 | |||
540 | /* Fine IT Min (A) */ | ||
541 | mt9t112_mcu_write(ret, client, VAR(18, 17), 0x01f1); | ||
542 | |||
543 | /* Fine IT Max Margin (A) */ | ||
544 | mt9t112_mcu_write(ret, client, VAR(18, 19), 0x00fF); | ||
545 | |||
546 | /* Base Frame Lines (A) */ | ||
547 | mt9t112_mcu_write(ret, client, VAR(18, 29), 0x032D); | ||
548 | |||
549 | /* Min Line Length (A) */ | ||
550 | mt9t112_mcu_write(ret, client, VAR(18, 31), 0x073a); | ||
551 | |||
552 | /* Line Length (A) */ | ||
553 | mt9t112_mcu_write(ret, client, VAR(18, 37), 0x07d0); | ||
554 | |||
555 | /* Adaptive Output Clock (B) */ | ||
556 | mt9t112_mcu_mask_set(ret, client, VAR(27, 160), 0x0040, 0x0000); | ||
557 | |||
558 | /* Row Start (B) */ | ||
559 | mt9t112_mcu_write(ret, client, VAR(18, 74), 0x004); | ||
560 | |||
561 | /* Column Start (B) */ | ||
562 | mt9t112_mcu_write(ret, client, VAR(18, 76), 0x004); | ||
563 | |||
564 | /* Row End (B) */ | ||
565 | mt9t112_mcu_write(ret, client, VAR(18, 78), 0x60B); | ||
566 | |||
567 | /* Column End (B) */ | ||
568 | mt9t112_mcu_write(ret, client, VAR(18, 80), 0x80B); | ||
569 | |||
570 | /* Fine Correction (B) */ | ||
571 | mt9t112_mcu_write(ret, client, VAR(18, 87), 0x008C); | ||
572 | |||
573 | /* Fine IT Min (B) */ | ||
574 | mt9t112_mcu_write(ret, client, VAR(18, 89), 0x01F1); | ||
575 | |||
576 | /* Fine IT Max Margin (B) */ | ||
577 | mt9t112_mcu_write(ret, client, VAR(18, 91), 0x00FF); | ||
578 | |||
579 | /* Base Frame Lines (B) */ | ||
580 | mt9t112_mcu_write(ret, client, VAR(18, 101), 0x0668); | ||
581 | |||
582 | /* Min Line Length (B) */ | ||
583 | mt9t112_mcu_write(ret, client, VAR(18, 103), 0x0AF0); | ||
584 | |||
585 | /* Line Length (B) */ | ||
586 | mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0); | ||
587 | |||
588 | /* | ||
589 | * Flicker Dectection registers | ||
590 | * This section should be replaced whenever new Timing file is generated | ||
591 | * All the following registers need to be replaced | ||
592 | * Following registers are generated from Register Wizard but user can | ||
593 | * modify them. For detail see auto flicker detection tuning | ||
594 | */ | ||
595 | |||
596 | /* FD_FDPERIOD_SELECT */ | ||
597 | mt9t112_mcu_write(ret, client, VAR8(8, 5), 0x01); | ||
598 | |||
599 | /* PRI_B_CONFIG_FD_ALGO_RUN */ | ||
600 | mt9t112_mcu_write(ret, client, VAR(27, 17), 0x0003); | ||
601 | |||
602 | /* PRI_A_CONFIG_FD_ALGO_RUN */ | ||
603 | mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003); | ||
604 | |||
605 | /* | ||
606 | * AFD range detection tuning registers | ||
607 | */ | ||
608 | |||
609 | /* search_f1_50 */ | ||
610 | mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25); | ||
611 | |||
612 | /* search_f2_50 */ | ||
613 | mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28); | ||
614 | |||
615 | /* search_f1_60 */ | ||
616 | mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C); | ||
617 | |||
618 | /* search_f2_60 */ | ||
619 | mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F); | ||
620 | |||
621 | /* period_50Hz (A) */ | ||
622 | mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA); | ||
623 | |||
624 | /* secret register by aptina */ | ||
625 | /* period_50Hz (A MSB) */ | ||
626 | mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00); | ||
627 | |||
628 | /* period_60Hz (A) */ | ||
629 | mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B); | ||
630 | |||
631 | /* secret register by aptina */ | ||
632 | /* period_60Hz (A MSB) */ | ||
633 | mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00); | ||
634 | |||
635 | /* period_50Hz (B) */ | ||
636 | mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82); | ||
637 | |||
638 | /* secret register by aptina */ | ||
639 | /* period_50Hz (B) MSB */ | ||
640 | mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00); | ||
641 | |||
642 | /* period_60Hz (B) */ | ||
643 | mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D); | ||
644 | |||
645 | /* secret register by aptina */ | ||
646 | /* period_60Hz (B) MSB */ | ||
647 | mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00); | ||
648 | |||
649 | /* FD Mode */ | ||
650 | mt9t112_mcu_write(ret, client, VAR8(8, 2), 0x10); | ||
651 | |||
652 | /* Stat_min */ | ||
653 | mt9t112_mcu_write(ret, client, VAR8(8, 9), 0x02); | ||
654 | |||
655 | /* Stat_max */ | ||
656 | mt9t112_mcu_write(ret, client, VAR8(8, 10), 0x03); | ||
657 | |||
658 | /* Min_amplitude */ | ||
659 | mt9t112_mcu_write(ret, client, VAR8(8, 12), 0x0A); | ||
660 | |||
661 | /* RX FIFO Watermark (A) */ | ||
662 | mt9t112_mcu_write(ret, client, VAR(18, 70), 0x0014); | ||
663 | |||
664 | /* RX FIFO Watermark (B) */ | ||
665 | mt9t112_mcu_write(ret, client, VAR(18, 142), 0x0014); | ||
666 | |||
667 | /* MCLK: 16MHz | ||
668 | * PCLK: 73MHz | ||
669 | * CorePixCLK: 36.5 MHz | ||
670 | */ | ||
671 | mt9t112_mcu_write(ret, client, VAR8(18, 0x0044), 133); | ||
672 | mt9t112_mcu_write(ret, client, VAR8(18, 0x0045), 110); | ||
673 | mt9t112_mcu_write(ret, client, VAR8(18, 0x008c), 130); | ||
674 | mt9t112_mcu_write(ret, client, VAR8(18, 0x008d), 108); | ||
675 | |||
676 | mt9t112_mcu_write(ret, client, VAR8(18, 0x00A5), 27); | ||
677 | mt9t112_mcu_write(ret, client, VAR8(18, 0x00a6), 30); | ||
678 | mt9t112_mcu_write(ret, client, VAR8(18, 0x00a7), 32); | ||
679 | mt9t112_mcu_write(ret, client, VAR8(18, 0x00a8), 35); | ||
680 | |||
681 | return ret; | ||
682 | } | ||
683 | |||
684 | static int mt9t112_auto_focus_setting(const struct i2c_client *client) | ||
685 | { | ||
686 | int ret; | ||
687 | |||
688 | mt9t112_mcu_write(ret, client, VAR(12, 13), 0x000F); | ||
689 | mt9t112_mcu_write(ret, client, VAR(12, 23), 0x0F0F); | ||
690 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); | ||
691 | |||
692 | mt9t112_reg_write(ret, client, 0x0614, 0x0000); | ||
693 | |||
694 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05); | ||
695 | mt9t112_mcu_write(ret, client, VAR8(12, 2), 0x02); | ||
696 | mt9t112_mcu_write(ret, client, VAR(12, 3), 0x0002); | ||
697 | mt9t112_mcu_write(ret, client, VAR(17, 3), 0x8001); | ||
698 | mt9t112_mcu_write(ret, client, VAR(17, 11), 0x0025); | ||
699 | mt9t112_mcu_write(ret, client, VAR(17, 13), 0x0193); | ||
700 | mt9t112_mcu_write(ret, client, VAR8(17, 33), 0x18); | ||
701 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05); | ||
702 | |||
703 | return ret; | ||
704 | } | ||
705 | |||
706 | static int mt9t112_auto_focus_trigger(const struct i2c_client *client) | ||
707 | { | ||
708 | int ret; | ||
709 | |||
710 | mt9t112_mcu_write(ret, client, VAR8(12, 25), 0x01); | ||
711 | |||
712 | return ret; | ||
713 | } | ||
714 | |||
715 | static int mt9t112_init_camera(const struct i2c_client *client) | ||
716 | { | ||
717 | int ret; | ||
718 | |||
719 | ECHECKER(ret, mt9t112_reset(client)); | ||
720 | |||
721 | ECHECKER(ret, mt9t112_init_pll(client)); | ||
722 | |||
723 | ECHECKER(ret, mt9t112_init_setting(client)); | ||
724 | |||
725 | ECHECKER(ret, mt9t112_auto_focus_setting(client)); | ||
726 | |||
727 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0); | ||
728 | |||
729 | /* Analog setting B */ | ||
730 | mt9t112_reg_write(ret, client, 0x3084, 0x2409); | ||
731 | mt9t112_reg_write(ret, client, 0x3092, 0x0A49); | ||
732 | mt9t112_reg_write(ret, client, 0x3094, 0x4949); | ||
733 | mt9t112_reg_write(ret, client, 0x3096, 0x4950); | ||
734 | |||
735 | /* | ||
736 | * Disable adaptive clock | ||
737 | * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR | ||
738 | * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR | ||
739 | */ | ||
740 | mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E); | ||
741 | mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E); | ||
742 | |||
743 | /* Configure STatus in Status_before_length Format and enable header */ | ||
744 | /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */ | ||
745 | mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4); | ||
746 | |||
747 | /* Enable JPEG in context B */ | ||
748 | /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */ | ||
749 | mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01); | ||
750 | |||
751 | /* Disable Dac_TXLO */ | ||
752 | mt9t112_reg_write(ret, client, 0x316C, 0x350F); | ||
753 | |||
754 | /* Set max slew rates */ | ||
755 | mt9t112_reg_write(ret, client, 0x1E, 0x777); | ||
756 | |||
757 | return ret; | ||
758 | } | ||
759 | |||
760 | /************************************************************************ | ||
761 | |||
762 | |||
763 | soc_camera_ops | ||
764 | |||
765 | |||
766 | ************************************************************************/ | ||
767 | static int mt9t112_set_bus_param(struct soc_camera_device *icd, | ||
768 | unsigned long flags) | ||
769 | { | ||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd) | ||
774 | { | ||
775 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
776 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
777 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
778 | unsigned long flags = SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH | | ||
779 | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH; | ||
780 | |||
781 | flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ? | ||
782 | SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING; | ||
783 | |||
784 | if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8) | ||
785 | flags |= SOCAM_DATAWIDTH_8; | ||
786 | else | ||
787 | flags |= SOCAM_DATAWIDTH_10; | ||
788 | |||
789 | return soc_camera_apply_sensor_flags(icl, flags); | ||
790 | } | ||
791 | |||
792 | static struct soc_camera_ops mt9t112_ops = { | ||
793 | .set_bus_param = mt9t112_set_bus_param, | ||
794 | .query_bus_param = mt9t112_query_bus_param, | ||
795 | }; | ||
796 | |||
797 | /************************************************************************ | ||
798 | |||
799 | |||
800 | v4l2_subdev_core_ops | ||
801 | |||
802 | |||
803 | ************************************************************************/ | ||
804 | static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, | ||
805 | struct v4l2_dbg_chip_ident *id) | ||
806 | { | ||
807 | struct i2c_client *client = sd->priv; | ||
808 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
809 | |||
810 | id->ident = priv->model; | ||
811 | id->revision = 0; | ||
812 | |||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
817 | static int mt9t112_g_register(struct v4l2_subdev *sd, | ||
818 | struct v4l2_dbg_register *reg) | ||
819 | { | ||
820 | struct i2c_client *client = sd->priv; | ||
821 | int ret; | ||
822 | |||
823 | reg->size = 2; | ||
824 | mt9t112_reg_read(ret, client, reg->reg); | ||
825 | |||
826 | reg->val = (__u64)ret; | ||
827 | |||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | static int mt9t112_s_register(struct v4l2_subdev *sd, | ||
832 | struct v4l2_dbg_register *reg) | ||
833 | { | ||
834 | struct i2c_client *client = sd->priv; | ||
835 | int ret; | ||
836 | |||
837 | mt9t112_reg_write(ret, client, reg->reg, reg->val); | ||
838 | |||
839 | return ret; | ||
840 | } | ||
841 | #endif | ||
842 | |||
843 | static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { | ||
844 | .g_chip_ident = mt9t112_g_chip_ident, | ||
845 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
846 | .g_register = mt9t112_g_register, | ||
847 | .s_register = mt9t112_s_register, | ||
848 | #endif | ||
849 | }; | ||
850 | |||
851 | |||
852 | /************************************************************************ | ||
853 | |||
854 | |||
855 | v4l2_subdev_video_ops | ||
856 | |||
857 | |||
858 | ************************************************************************/ | ||
859 | static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) | ||
860 | { | ||
861 | struct i2c_client *client = sd->priv; | ||
862 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
863 | int ret = 0; | ||
864 | |||
865 | if (!enable) { | ||
866 | /* FIXME | ||
867 | * | ||
868 | * If user selected large output size, | ||
869 | * and used it long time, | ||
870 | * mt9t112 camera will be very warm. | ||
871 | * | ||
872 | * But current driver can not stop mt9t112 camera. | ||
873 | * So, set small size here to solve this problem. | ||
874 | */ | ||
875 | mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT); | ||
876 | return ret; | ||
877 | } | ||
878 | |||
879 | if (!(priv->flags & INIT_DONE)) { | ||
880 | u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE & | ||
881 | priv->info->flags) ? 0x0001 : 0x0000; | ||
882 | |||
883 | ECHECKER(ret, mt9t112_init_camera(client)); | ||
884 | |||
885 | /* Invert PCLK (Data sampled on falling edge of pixclk) */ | ||
886 | mt9t112_reg_write(ret, client, 0x3C20, param); | ||
887 | |||
888 | mdelay(5); | ||
889 | |||
890 | priv->flags |= INIT_DONE; | ||
891 | } | ||
892 | |||
893 | mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt); | ||
894 | mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order); | ||
895 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); | ||
896 | |||
897 | mt9t112_set_a_frame_size(client, | ||
898 | priv->frame.width, | ||
899 | priv->frame.height); | ||
900 | |||
901 | ECHECKER(ret, mt9t112_auto_focus_trigger(client)); | ||
902 | |||
903 | dev_dbg(&client->dev, "format : %d\n", priv->format->code); | ||
904 | dev_dbg(&client->dev, "size : %d x %d\n", | ||
905 | priv->frame.width, | ||
906 | priv->frame.height); | ||
907 | |||
908 | CLOCK_INFO(client, EXT_CLOCK); | ||
909 | |||
910 | return ret; | ||
911 | } | ||
912 | |||
913 | static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height, | ||
914 | enum v4l2_mbus_pixelcode code) | ||
915 | { | ||
916 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
917 | int i; | ||
918 | |||
919 | priv->format = NULL; | ||
920 | |||
921 | /* | ||
922 | * frame size check | ||
923 | */ | ||
924 | mt9t112_frame_check(&width, &height); | ||
925 | |||
926 | /* | ||
927 | * get color format | ||
928 | */ | ||
929 | for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++) | ||
930 | if (mt9t112_cfmts[i].code == code) | ||
931 | break; | ||
932 | |||
933 | if (i == ARRAY_SIZE(mt9t112_cfmts)) | ||
934 | return -EINVAL; | ||
935 | |||
936 | priv->frame.width = (u16)width; | ||
937 | priv->frame.height = (u16)height; | ||
938 | |||
939 | priv->format = mt9t112_cfmts + i; | ||
940 | |||
941 | return 0; | ||
942 | } | ||
943 | |||
944 | static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | ||
945 | { | ||
946 | a->bounds.left = 0; | ||
947 | a->bounds.top = 0; | ||
948 | a->bounds.width = VGA_WIDTH; | ||
949 | a->bounds.height = VGA_HEIGHT; | ||
950 | a->defrect = a->bounds; | ||
951 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
952 | a->pixelaspect.numerator = 1; | ||
953 | a->pixelaspect.denominator = 1; | ||
954 | |||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | ||
959 | { | ||
960 | a->c.left = 0; | ||
961 | a->c.top = 0; | ||
962 | a->c.width = VGA_WIDTH; | ||
963 | a->c.height = VGA_HEIGHT; | ||
964 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
965 | |||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | ||
970 | { | ||
971 | struct i2c_client *client = sd->priv; | ||
972 | struct v4l2_rect *rect = &a->c; | ||
973 | |||
974 | return mt9t112_set_params(client, rect->width, rect->height, | ||
975 | V4L2_MBUS_FMT_YUYV8_2X8_BE); | ||
976 | } | ||
977 | |||
978 | static int mt9t112_g_fmt(struct v4l2_subdev *sd, | ||
979 | struct v4l2_mbus_framefmt *mf) | ||
980 | { | ||
981 | struct i2c_client *client = sd->priv; | ||
982 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
983 | |||
984 | if (!priv->format) { | ||
985 | int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT, | ||
986 | V4L2_MBUS_FMT_YUYV8_2X8_BE); | ||
987 | if (ret < 0) | ||
988 | return ret; | ||
989 | } | ||
990 | |||
991 | mf->width = priv->frame.width; | ||
992 | mf->height = priv->frame.height; | ||
993 | /* TODO: set colorspace */ | ||
994 | mf->code = priv->format->code; | ||
995 | mf->field = V4L2_FIELD_NONE; | ||
996 | |||
997 | return 0; | ||
998 | } | ||
999 | |||
1000 | static int mt9t112_s_fmt(struct v4l2_subdev *sd, | ||
1001 | struct v4l2_mbus_framefmt *mf) | ||
1002 | { | ||
1003 | struct i2c_client *client = sd->priv; | ||
1004 | |||
1005 | /* TODO: set colorspace */ | ||
1006 | return mt9t112_set_params(client, mf->width, mf->height, mf->code); | ||
1007 | } | ||
1008 | |||
1009 | static int mt9t112_try_fmt(struct v4l2_subdev *sd, | ||
1010 | struct v4l2_mbus_framefmt *mf) | ||
1011 | { | ||
1012 | mt9t112_frame_check(&mf->width, &mf->height); | ||
1013 | |||
1014 | /* TODO: set colorspace */ | ||
1015 | mf->field = V4L2_FIELD_NONE; | ||
1016 | |||
1017 | return 0; | ||
1018 | } | ||
1019 | |||
1020 | static int mt9t112_enum_fmt(struct v4l2_subdev *sd, int index, | ||
1021 | enum v4l2_mbus_pixelcode *code) | ||
1022 | { | ||
1023 | if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts)) | ||
1024 | return -EINVAL; | ||
1025 | |||
1026 | *code = mt9t112_cfmts[index].code; | ||
1027 | return 0; | ||
1028 | } | ||
1029 | |||
1030 | static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { | ||
1031 | .s_stream = mt9t112_s_stream, | ||
1032 | .g_mbus_fmt = mt9t112_g_fmt, | ||
1033 | .s_mbus_fmt = mt9t112_s_fmt, | ||
1034 | .try_mbus_fmt = mt9t112_try_fmt, | ||
1035 | .cropcap = mt9t112_cropcap, | ||
1036 | .g_crop = mt9t112_g_crop, | ||
1037 | .s_crop = mt9t112_s_crop, | ||
1038 | .enum_mbus_fmt = mt9t112_enum_fmt, | ||
1039 | }; | ||
1040 | |||
1041 | /************************************************************************ | ||
1042 | |||
1043 | |||
1044 | i2c driver | ||
1045 | |||
1046 | |||
1047 | ************************************************************************/ | ||
1048 | static struct v4l2_subdev_ops mt9t112_subdev_ops = { | ||
1049 | .core = &mt9t112_subdev_core_ops, | ||
1050 | .video = &mt9t112_subdev_video_ops, | ||
1051 | }; | ||
1052 | |||
1053 | static int mt9t112_camera_probe(struct soc_camera_device *icd, | ||
1054 | struct i2c_client *client) | ||
1055 | { | ||
1056 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
1057 | const char *devname; | ||
1058 | int chipid; | ||
1059 | |||
1060 | /* | ||
1061 | * We must have a parent by now. And it cannot be a wrong one. | ||
1062 | * So this entire test is completely redundant. | ||
1063 | */ | ||
1064 | if (!icd->dev.parent || | ||
1065 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) | ||
1066 | return -ENODEV; | ||
1067 | |||
1068 | /* | ||
1069 | * check and show chip ID | ||
1070 | */ | ||
1071 | mt9t112_reg_read(chipid, client, 0x0000); | ||
1072 | |||
1073 | switch (chipid) { | ||
1074 | case 0x2680: | ||
1075 | devname = "mt9t111"; | ||
1076 | priv->model = V4L2_IDENT_MT9T111; | ||
1077 | break; | ||
1078 | case 0x2682: | ||
1079 | devname = "mt9t112"; | ||
1080 | priv->model = V4L2_IDENT_MT9T112; | ||
1081 | break; | ||
1082 | default: | ||
1083 | dev_err(&client->dev, "Product ID error %04x\n", chipid); | ||
1084 | return -ENODEV; | ||
1085 | } | ||
1086 | |||
1087 | dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid); | ||
1088 | |||
1089 | return 0; | ||
1090 | } | ||
1091 | |||
1092 | static int mt9t112_probe(struct i2c_client *client, | ||
1093 | const struct i2c_device_id *did) | ||
1094 | { | ||
1095 | struct mt9t112_priv *priv; | ||
1096 | struct soc_camera_device *icd = client->dev.platform_data; | ||
1097 | struct soc_camera_link *icl; | ||
1098 | int ret; | ||
1099 | |||
1100 | if (!icd) { | ||
1101 | dev_err(&client->dev, "mt9t112: missing soc-camera data!\n"); | ||
1102 | return -EINVAL; | ||
1103 | } | ||
1104 | |||
1105 | icl = to_soc_camera_link(icd); | ||
1106 | if (!icl || !icl->priv) | ||
1107 | return -EINVAL; | ||
1108 | |||
1109 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
1110 | if (!priv) | ||
1111 | return -ENOMEM; | ||
1112 | |||
1113 | priv->info = icl->priv; | ||
1114 | |||
1115 | v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); | ||
1116 | |||
1117 | icd->ops = &mt9t112_ops; | ||
1118 | |||
1119 | ret = mt9t112_camera_probe(icd, client); | ||
1120 | if (ret) { | ||
1121 | icd->ops = NULL; | ||
1122 | i2c_set_clientdata(client, NULL); | ||
1123 | kfree(priv); | ||
1124 | } | ||
1125 | |||
1126 | return ret; | ||
1127 | } | ||
1128 | |||
1129 | static int mt9t112_remove(struct i2c_client *client) | ||
1130 | { | ||
1131 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
1132 | struct soc_camera_device *icd = client->dev.platform_data; | ||
1133 | |||
1134 | icd->ops = NULL; | ||
1135 | i2c_set_clientdata(client, NULL); | ||
1136 | kfree(priv); | ||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
1140 | static const struct i2c_device_id mt9t112_id[] = { | ||
1141 | { "mt9t112", 0 }, | ||
1142 | { } | ||
1143 | }; | ||
1144 | MODULE_DEVICE_TABLE(i2c, mt9t112_id); | ||
1145 | |||
1146 | static struct i2c_driver mt9t112_i2c_driver = { | ||
1147 | .driver = { | ||
1148 | .name = "mt9t112", | ||
1149 | }, | ||
1150 | .probe = mt9t112_probe, | ||
1151 | .remove = mt9t112_remove, | ||
1152 | .id_table = mt9t112_id, | ||
1153 | }; | ||
1154 | |||
1155 | /************************************************************************ | ||
1156 | |||
1157 | |||
1158 | module function | ||
1159 | |||
1160 | |||
1161 | ************************************************************************/ | ||
1162 | static int __init mt9t112_module_init(void) | ||
1163 | { | ||
1164 | return i2c_add_driver(&mt9t112_i2c_driver); | ||
1165 | } | ||
1166 | |||
1167 | static void __exit mt9t112_module_exit(void) | ||
1168 | { | ||
1169 | i2c_del_driver(&mt9t112_i2c_driver); | ||
1170 | } | ||
1171 | |||
1172 | module_init(mt9t112_module_init); | ||
1173 | module_exit(mt9t112_module_exit); | ||
1174 | |||
1175 | MODULE_DESCRIPTION("SoC Camera driver for mt9t112"); | ||
1176 | MODULE_AUTHOR("Kuninori Morimoto"); | ||
1177 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 995607f9d3b..91df7ec91fb 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -18,9 +18,11 @@ | |||
18 | #include <media/v4l2-chip-ident.h> | 18 | #include <media/v4l2-chip-ident.h> |
19 | #include <media/soc_camera.h> | 19 | #include <media/soc_camera.h> |
20 | 20 | ||
21 | /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c | 21 | /* |
22 | * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c | ||
22 | * The platform has to define ctruct i2c_board_info objects and link to them | 23 | * The platform has to define ctruct i2c_board_info objects and link to them |
23 | * from struct soc_camera_link */ | 24 | * from struct soc_camera_link |
25 | */ | ||
24 | 26 | ||
25 | static char *sensor_type; | 27 | static char *sensor_type; |
26 | module_param(sensor_type, charp, S_IRUGO); | 28 | module_param(sensor_type, charp, S_IRUGO); |
@@ -62,41 +64,49 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\""); | |||
62 | #define MT9V022_COLUMN_SKIP 1 | 64 | #define MT9V022_COLUMN_SKIP 1 |
63 | #define MT9V022_ROW_SKIP 4 | 65 | #define MT9V022_ROW_SKIP 4 |
64 | 66 | ||
65 | static const struct soc_camera_data_format mt9v022_colour_formats[] = { | 67 | /* MT9V022 has only one fixed colorspace per pixelcode */ |
66 | /* Order important: first natively supported, | 68 | struct mt9v022_datafmt { |
67 | * second supported with a GPIO extender */ | 69 | enum v4l2_mbus_pixelcode code; |
68 | { | 70 | enum v4l2_colorspace colorspace; |
69 | .name = "Bayer (sRGB) 10 bit", | 71 | }; |
70 | .depth = 10, | 72 | |
71 | .fourcc = V4L2_PIX_FMT_SBGGR16, | 73 | /* Find a data format by a pixel code in an array */ |
72 | .colorspace = V4L2_COLORSPACE_SRGB, | 74 | static const struct mt9v022_datafmt *mt9v022_find_datafmt( |
73 | }, { | 75 | enum v4l2_mbus_pixelcode code, const struct mt9v022_datafmt *fmt, |
74 | .name = "Bayer (sRGB) 8 bit", | 76 | int n) |
75 | .depth = 8, | 77 | { |
76 | .fourcc = V4L2_PIX_FMT_SBGGR8, | 78 | int i; |
77 | .colorspace = V4L2_COLORSPACE_SRGB, | 79 | for (i = 0; i < n; i++) |
78 | } | 80 | if (fmt[i].code == code) |
81 | return fmt + i; | ||
82 | |||
83 | return NULL; | ||
84 | } | ||
85 | |||
86 | static const struct mt9v022_datafmt mt9v022_colour_fmts[] = { | ||
87 | /* | ||
88 | * Order important: first natively supported, | ||
89 | * second supported with a GPIO extender | ||
90 | */ | ||
91 | {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, | ||
92 | {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, | ||
79 | }; | 93 | }; |
80 | 94 | ||
81 | static const struct soc_camera_data_format mt9v022_monochrome_formats[] = { | 95 | static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = { |
82 | /* Order important - see above */ | 96 | /* Order important - see above */ |
83 | { | 97 | {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, |
84 | .name = "Monochrome 10 bit", | 98 | {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, |
85 | .depth = 10, | ||
86 | .fourcc = V4L2_PIX_FMT_Y16, | ||
87 | }, { | ||
88 | .name = "Monochrome 8 bit", | ||
89 | .depth = 8, | ||
90 | .fourcc = V4L2_PIX_FMT_GREY, | ||
91 | }, | ||
92 | }; | 99 | }; |
93 | 100 | ||
94 | struct mt9v022 { | 101 | struct mt9v022 { |
95 | struct v4l2_subdev subdev; | 102 | struct v4l2_subdev subdev; |
96 | struct v4l2_rect rect; /* Sensor window */ | 103 | struct v4l2_rect rect; /* Sensor window */ |
97 | __u32 fourcc; | 104 | const struct mt9v022_datafmt *fmt; |
105 | const struct mt9v022_datafmt *fmts; | ||
106 | int num_fmts; | ||
98 | int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ | 107 | int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ |
99 | u16 chip_control; | 108 | u16 chip_control; |
109 | unsigned short y_skip_top; /* Lines to skip at the top */ | ||
100 | }; | 110 | }; |
101 | 111 | ||
102 | static struct mt9v022 *to_mt9v022(const struct i2c_client *client) | 112 | static struct mt9v022 *to_mt9v022(const struct i2c_client *client) |
@@ -143,9 +153,11 @@ static int mt9v022_init(struct i2c_client *client) | |||
143 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 153 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
144 | int ret; | 154 | int ret; |
145 | 155 | ||
146 | /* Almost the default mode: master, parallel, simultaneous, and an | 156 | /* |
157 | * Almost the default mode: master, parallel, simultaneous, and an | ||
147 | * undocumented bit 0x200, which is present in table 7, but not in 8, | 158 | * undocumented bit 0x200, which is present in table 7, but not in 8, |
148 | * plus snapshot mode to disable scan for now */ | 159 | * plus snapshot mode to disable scan for now |
160 | */ | ||
149 | mt9v022->chip_control |= 0x10; | 161 | mt9v022->chip_control |= 0x10; |
150 | ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); | 162 | ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control); |
151 | if (!ret) | 163 | if (!ret) |
@@ -265,12 +277,10 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
265 | struct i2c_client *client = sd->priv; | 277 | struct i2c_client *client = sd->priv; |
266 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 278 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
267 | struct v4l2_rect rect = a->c; | 279 | struct v4l2_rect rect = a->c; |
268 | struct soc_camera_device *icd = client->dev.platform_data; | ||
269 | int ret; | 280 | int ret; |
270 | 281 | ||
271 | /* Bayer format - even size lengths */ | 282 | /* Bayer format - even size lengths */ |
272 | if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 || | 283 | if (mt9v022->fmts == mt9v022_colour_fmts) { |
273 | mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) { | ||
274 | rect.width = ALIGN(rect.width, 2); | 284 | rect.width = ALIGN(rect.width, 2); |
275 | rect.height = ALIGN(rect.height, 2); | 285 | rect.height = ALIGN(rect.height, 2); |
276 | /* Let the user play with the starting pixel */ | 286 | /* Let the user play with the starting pixel */ |
@@ -287,10 +297,10 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
287 | if (ret >= 0) { | 297 | if (ret >= 0) { |
288 | if (ret & 1) /* Autoexposure */ | 298 | if (ret & 1) /* Autoexposure */ |
289 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, | 299 | ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, |
290 | rect.height + icd->y_skip_top + 43); | 300 | rect.height + mt9v022->y_skip_top + 43); |
291 | else | 301 | else |
292 | ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, | 302 | ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, |
293 | rect.height + icd->y_skip_top + 43); | 303 | rect.height + mt9v022->y_skip_top + 43); |
294 | } | 304 | } |
295 | /* Setup frame format: defaults apart from width and height */ | 305 | /* Setup frame format: defaults apart from width and height */ |
296 | if (!ret) | 306 | if (!ret) |
@@ -298,8 +308,10 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
298 | if (!ret) | 308 | if (!ret) |
299 | ret = reg_write(client, MT9V022_ROW_START, rect.top); | 309 | ret = reg_write(client, MT9V022_ROW_START, rect.top); |
300 | if (!ret) | 310 | if (!ret) |
301 | /* Default 94, Phytec driver says: | 311 | /* |
302 | * "width + horizontal blank >= 660" */ | 312 | * Default 94, Phytec driver says: |
313 | * "width + horizontal blank >= 660" | ||
314 | */ | ||
303 | ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, | 315 | ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, |
304 | rect.width > 660 - 43 ? 43 : | 316 | rect.width > 660 - 43 ? 43 : |
305 | 660 - rect.width); | 317 | 660 - rect.width); |
@@ -309,7 +321,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
309 | ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width); | 321 | ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width); |
310 | if (!ret) | 322 | if (!ret) |
311 | ret = reg_write(client, MT9V022_WINDOW_HEIGHT, | 323 | ret = reg_write(client, MT9V022_WINDOW_HEIGHT, |
312 | rect.height + icd->y_skip_top); | 324 | rect.height + mt9v022->y_skip_top); |
313 | 325 | ||
314 | if (ret < 0) | 326 | if (ret < 0) |
315 | return ret; | 327 | return ret; |
@@ -346,46 +358,48 @@ static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
346 | return 0; | 358 | return 0; |
347 | } | 359 | } |
348 | 360 | ||
349 | static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 361 | static int mt9v022_g_fmt(struct v4l2_subdev *sd, |
362 | struct v4l2_mbus_framefmt *mf) | ||
350 | { | 363 | { |
351 | struct i2c_client *client = sd->priv; | 364 | struct i2c_client *client = sd->priv; |
352 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 365 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
353 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
354 | 366 | ||
355 | pix->width = mt9v022->rect.width; | 367 | mf->width = mt9v022->rect.width; |
356 | pix->height = mt9v022->rect.height; | 368 | mf->height = mt9v022->rect.height; |
357 | pix->pixelformat = mt9v022->fourcc; | 369 | mf->code = mt9v022->fmt->code; |
358 | pix->field = V4L2_FIELD_NONE; | 370 | mf->colorspace = mt9v022->fmt->colorspace; |
359 | pix->colorspace = V4L2_COLORSPACE_SRGB; | 371 | mf->field = V4L2_FIELD_NONE; |
360 | 372 | ||
361 | return 0; | 373 | return 0; |
362 | } | 374 | } |
363 | 375 | ||
364 | static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 376 | static int mt9v022_s_fmt(struct v4l2_subdev *sd, |
377 | struct v4l2_mbus_framefmt *mf) | ||
365 | { | 378 | { |
366 | struct i2c_client *client = sd->priv; | 379 | struct i2c_client *client = sd->priv; |
367 | struct mt9v022 *mt9v022 = to_mt9v022(client); | 380 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
368 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
369 | struct v4l2_crop a = { | 381 | struct v4l2_crop a = { |
370 | .c = { | 382 | .c = { |
371 | .left = mt9v022->rect.left, | 383 | .left = mt9v022->rect.left, |
372 | .top = mt9v022->rect.top, | 384 | .top = mt9v022->rect.top, |
373 | .width = pix->width, | 385 | .width = mf->width, |
374 | .height = pix->height, | 386 | .height = mf->height, |
375 | }, | 387 | }, |
376 | }; | 388 | }; |
377 | int ret; | 389 | int ret; |
378 | 390 | ||
379 | /* The caller provides a supported format, as verified per call to | 391 | /* |
380 | * icd->try_fmt(), datawidth is from our supported format list */ | 392 | * The caller provides a supported format, as verified per call to |
381 | switch (pix->pixelformat) { | 393 | * icd->try_fmt(), datawidth is from our supported format list |
382 | case V4L2_PIX_FMT_GREY: | 394 | */ |
383 | case V4L2_PIX_FMT_Y16: | 395 | switch (mf->code) { |
396 | case V4L2_MBUS_FMT_GREY8_1X8: | ||
397 | case V4L2_MBUS_FMT_Y10_1X10: | ||
384 | if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) | 398 | if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) |
385 | return -EINVAL; | 399 | return -EINVAL; |
386 | break; | 400 | break; |
387 | case V4L2_PIX_FMT_SBGGR8: | 401 | case V4L2_MBUS_FMT_SBGGR8_1X8: |
388 | case V4L2_PIX_FMT_SBGGR16: | 402 | case V4L2_MBUS_FMT_SBGGR10_1X10: |
389 | if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) | 403 | if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) |
390 | return -EINVAL; | 404 | return -EINVAL; |
391 | break; | 405 | break; |
@@ -399,26 +413,38 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |||
399 | /* No support for scaling on this camera, just crop. */ | 413 | /* No support for scaling on this camera, just crop. */ |
400 | ret = mt9v022_s_crop(sd, &a); | 414 | ret = mt9v022_s_crop(sd, &a); |
401 | if (!ret) { | 415 | if (!ret) { |
402 | pix->width = mt9v022->rect.width; | 416 | mf->width = mt9v022->rect.width; |
403 | pix->height = mt9v022->rect.height; | 417 | mf->height = mt9v022->rect.height; |
404 | mt9v022->fourcc = pix->pixelformat; | 418 | mt9v022->fmt = mt9v022_find_datafmt(mf->code, |
419 | mt9v022->fmts, mt9v022->num_fmts); | ||
420 | mf->colorspace = mt9v022->fmt->colorspace; | ||
405 | } | 421 | } |
406 | 422 | ||
407 | return ret; | 423 | return ret; |
408 | } | 424 | } |
409 | 425 | ||
410 | static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 426 | static int mt9v022_try_fmt(struct v4l2_subdev *sd, |
427 | struct v4l2_mbus_framefmt *mf) | ||
411 | { | 428 | { |
412 | struct i2c_client *client = sd->priv; | 429 | struct i2c_client *client = sd->priv; |
413 | struct soc_camera_device *icd = client->dev.platform_data; | 430 | struct mt9v022 *mt9v022 = to_mt9v022(client); |
414 | struct v4l2_pix_format *pix = &f->fmt.pix; | 431 | const struct mt9v022_datafmt *fmt; |
415 | int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || | 432 | int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || |
416 | pix->pixelformat == V4L2_PIX_FMT_SBGGR16; | 433 | mf->code == V4L2_MBUS_FMT_SBGGR10_1X10; |
417 | 434 | ||
418 | v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH, | 435 | v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH, |
419 | MT9V022_MAX_WIDTH, align, | 436 | MT9V022_MAX_WIDTH, align, |
420 | &pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top, | 437 | &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top, |
421 | MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0); | 438 | MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0); |
439 | |||
440 | fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts, | ||
441 | mt9v022->num_fmts); | ||
442 | if (!fmt) { | ||
443 | fmt = mt9v022->fmt; | ||
444 | mf->code = fmt->code; | ||
445 | } | ||
446 | |||
447 | mf->colorspace = fmt->colorspace; | ||
422 | 448 | ||
423 | return 0; | 449 | return 0; |
424 | } | 450 | } |
@@ -635,8 +661,10 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
635 | 48 + range / 2) / range + 16; | 661 | 48 + range / 2) / range + 16; |
636 | if (gain >= 32) | 662 | if (gain >= 32) |
637 | gain &= ~1; | 663 | gain &= ~1; |
638 | /* The user wants to set gain manually, hope, she | 664 | /* |
639 | * knows, what she's doing... Switch AGC off. */ | 665 | * The user wants to set gain manually, hope, she |
666 | * knows, what she's doing... Switch AGC off. | ||
667 | */ | ||
640 | 668 | ||
641 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) | 669 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) |
642 | return -EIO; | 670 | return -EIO; |
@@ -655,8 +683,10 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
655 | unsigned long range = qctrl->maximum - qctrl->minimum; | 683 | unsigned long range = qctrl->maximum - qctrl->minimum; |
656 | unsigned long shutter = ((ctrl->value - qctrl->minimum) * | 684 | unsigned long shutter = ((ctrl->value - qctrl->minimum) * |
657 | 479 + range / 2) / range + 1; | 685 | 479 + range / 2) / range + 1; |
658 | /* The user wants to set shutter width manually, hope, | 686 | /* |
659 | * she knows, what she's doing... Switch AEC off. */ | 687 | * The user wants to set shutter width manually, hope, |
688 | * she knows, what she's doing... Switch AEC off. | ||
689 | */ | ||
660 | 690 | ||
661 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) | 691 | if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) |
662 | return -EIO; | 692 | return -EIO; |
@@ -689,8 +719,10 @@ static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
689 | return 0; | 719 | return 0; |
690 | } | 720 | } |
691 | 721 | ||
692 | /* Interface active, can use i2c. If it fails, it can indeed mean, that | 722 | /* |
693 | * this wasn't our capture interface, so, we wait for the right one */ | 723 | * Interface active, can use i2c. If it fails, it can indeed mean, that |
724 | * this wasn't our capture interface, so, we wait for the right one | ||
725 | */ | ||
694 | static int mt9v022_video_probe(struct soc_camera_device *icd, | 726 | static int mt9v022_video_probe(struct soc_camera_device *icd, |
695 | struct i2c_client *client) | 727 | struct i2c_client *client) |
696 | { | 728 | { |
@@ -733,17 +765,17 @@ static int mt9v022_video_probe(struct soc_camera_device *icd, | |||
733 | !strcmp("color", sensor_type))) { | 765 | !strcmp("color", sensor_type))) { |
734 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); | 766 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); |
735 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; | 767 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; |
736 | icd->formats = mt9v022_colour_formats; | 768 | mt9v022->fmts = mt9v022_colour_fmts; |
737 | } else { | 769 | } else { |
738 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); | 770 | ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); |
739 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; | 771 | mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; |
740 | icd->formats = mt9v022_monochrome_formats; | 772 | mt9v022->fmts = mt9v022_monochrome_fmts; |
741 | } | 773 | } |
742 | 774 | ||
743 | if (ret < 0) | 775 | if (ret < 0) |
744 | goto ei2c; | 776 | goto ei2c; |
745 | 777 | ||
746 | icd->num_formats = 0; | 778 | mt9v022->num_fmts = 0; |
747 | 779 | ||
748 | /* | 780 | /* |
749 | * This is a 10bit sensor, so by default we only allow 10bit. | 781 | * This is a 10bit sensor, so by default we only allow 10bit. |
@@ -756,14 +788,14 @@ static int mt9v022_video_probe(struct soc_camera_device *icd, | |||
756 | flags = SOCAM_DATAWIDTH_10; | 788 | flags = SOCAM_DATAWIDTH_10; |
757 | 789 | ||
758 | if (flags & SOCAM_DATAWIDTH_10) | 790 | if (flags & SOCAM_DATAWIDTH_10) |
759 | icd->num_formats++; | 791 | mt9v022->num_fmts++; |
760 | else | 792 | else |
761 | icd->formats++; | 793 | mt9v022->fmts++; |
762 | 794 | ||
763 | if (flags & SOCAM_DATAWIDTH_8) | 795 | if (flags & SOCAM_DATAWIDTH_8) |
764 | icd->num_formats++; | 796 | mt9v022->num_fmts++; |
765 | 797 | ||
766 | mt9v022->fourcc = icd->formats->fourcc; | 798 | mt9v022->fmt = &mt9v022->fmts[0]; |
767 | 799 | ||
768 | dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", | 800 | dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", |
769 | data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? | 801 | data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? |
@@ -787,6 +819,16 @@ static void mt9v022_video_remove(struct soc_camera_device *icd) | |||
787 | icl->free_bus(icl); | 819 | icl->free_bus(icl); |
788 | } | 820 | } |
789 | 821 | ||
822 | static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) | ||
823 | { | ||
824 | struct i2c_client *client = sd->priv; | ||
825 | struct mt9v022 *mt9v022 = to_mt9v022(client); | ||
826 | |||
827 | *lines = mt9v022->y_skip_top; | ||
828 | |||
829 | return 0; | ||
830 | } | ||
831 | |||
790 | static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { | 832 | static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { |
791 | .g_ctrl = mt9v022_g_ctrl, | 833 | .g_ctrl = mt9v022_g_ctrl, |
792 | .s_ctrl = mt9v022_s_ctrl, | 834 | .s_ctrl = mt9v022_s_ctrl, |
@@ -797,19 +839,38 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { | |||
797 | #endif | 839 | #endif |
798 | }; | 840 | }; |
799 | 841 | ||
842 | static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index, | ||
843 | enum v4l2_mbus_pixelcode *code) | ||
844 | { | ||
845 | struct i2c_client *client = sd->priv; | ||
846 | struct mt9v022 *mt9v022 = to_mt9v022(client); | ||
847 | |||
848 | if ((unsigned int)index >= mt9v022->num_fmts) | ||
849 | return -EINVAL; | ||
850 | |||
851 | *code = mt9v022->fmts[index].code; | ||
852 | return 0; | ||
853 | } | ||
854 | |||
800 | static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { | 855 | static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { |
801 | .s_stream = mt9v022_s_stream, | 856 | .s_stream = mt9v022_s_stream, |
802 | .s_fmt = mt9v022_s_fmt, | 857 | .s_mbus_fmt = mt9v022_s_fmt, |
803 | .g_fmt = mt9v022_g_fmt, | 858 | .g_mbus_fmt = mt9v022_g_fmt, |
804 | .try_fmt = mt9v022_try_fmt, | 859 | .try_mbus_fmt = mt9v022_try_fmt, |
805 | .s_crop = mt9v022_s_crop, | 860 | .s_crop = mt9v022_s_crop, |
806 | .g_crop = mt9v022_g_crop, | 861 | .g_crop = mt9v022_g_crop, |
807 | .cropcap = mt9v022_cropcap, | 862 | .cropcap = mt9v022_cropcap, |
863 | .enum_mbus_fmt = mt9v022_enum_fmt, | ||
864 | }; | ||
865 | |||
866 | static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { | ||
867 | .g_skip_top_lines = mt9v022_g_skip_top_lines, | ||
808 | }; | 868 | }; |
809 | 869 | ||
810 | static struct v4l2_subdev_ops mt9v022_subdev_ops = { | 870 | static struct v4l2_subdev_ops mt9v022_subdev_ops = { |
811 | .core = &mt9v022_subdev_core_ops, | 871 | .core = &mt9v022_subdev_core_ops, |
812 | .video = &mt9v022_subdev_video_ops, | 872 | .video = &mt9v022_subdev_video_ops, |
873 | .sensor = &mt9v022_subdev_sensor_ops, | ||
813 | }; | 874 | }; |
814 | 875 | ||
815 | static int mt9v022_probe(struct i2c_client *client, | 876 | static int mt9v022_probe(struct i2c_client *client, |
@@ -851,8 +912,7 @@ static int mt9v022_probe(struct i2c_client *client, | |||
851 | * MT9V022 _really_ corrupts the first read out line. | 912 | * MT9V022 _really_ corrupts the first read out line. |
852 | * TODO: verify on i.MX31 | 913 | * TODO: verify on i.MX31 |
853 | */ | 914 | */ |
854 | icd->y_skip_top = 1; | 915 | mt9v022->y_skip_top = 1; |
855 | |||
856 | mt9v022->rect.left = MT9V022_COLUMN_SKIP; | 916 | mt9v022->rect.left = MT9V022_COLUMN_SKIP; |
857 | mt9v022->rect.top = MT9V022_ROW_SKIP; | 917 | mt9v022->rect.top = MT9V022_ROW_SKIP; |
858 | mt9v022->rect.width = MT9V022_MAX_WIDTH; | 918 | mt9v022->rect.width = MT9V022_MAX_WIDTH; |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 72802291e81..2ba14fb5b03 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
38 | #include <media/v4l2-dev.h> | 38 | #include <media/v4l2-dev.h> |
39 | #include <media/videobuf-dma-contig.h> | 39 | #include <media/videobuf-dma-contig.h> |
40 | #include <media/soc_mediabus.h> | ||
40 | 41 | ||
41 | #include <asm/dma.h> | 42 | #include <asm/dma.h> |
42 | #include <asm/fiq.h> | 43 | #include <asm/fiq.h> |
@@ -94,14 +95,16 @@ | |||
94 | /* buffer for one video frame */ | 95 | /* buffer for one video frame */ |
95 | struct mx1_buffer { | 96 | struct mx1_buffer { |
96 | /* common v4l buffer stuff -- must be first */ | 97 | /* common v4l buffer stuff -- must be first */ |
97 | struct videobuf_buffer vb; | 98 | struct videobuf_buffer vb; |
98 | const struct soc_camera_data_format *fmt; | 99 | enum v4l2_mbus_pixelcode code; |
99 | int inwork; | 100 | int inwork; |
100 | }; | 101 | }; |
101 | 102 | ||
102 | /* i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor | 103 | /* |
104 | * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor | ||
103 | * Interface. If anyone ever builds hardware to enable more than | 105 | * Interface. If anyone ever builds hardware to enable more than |
104 | * one camera, they will have to modify this driver too */ | 106 | * one camera, they will have to modify this driver too |
107 | */ | ||
105 | struct mx1_camera_dev { | 108 | struct mx1_camera_dev { |
106 | struct soc_camera_host soc_host; | 109 | struct soc_camera_host soc_host; |
107 | struct soc_camera_device *icd; | 110 | struct soc_camera_device *icd; |
@@ -126,9 +129,13 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, | |||
126 | unsigned int *size) | 129 | unsigned int *size) |
127 | { | 130 | { |
128 | struct soc_camera_device *icd = vq->priv_data; | 131 | struct soc_camera_device *icd = vq->priv_data; |
132 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
133 | icd->current_fmt->host_fmt); | ||
134 | |||
135 | if (bytes_per_line < 0) | ||
136 | return bytes_per_line; | ||
129 | 137 | ||
130 | *size = icd->user_width * icd->user_height * | 138 | *size = bytes_per_line * icd->user_height; |
131 | ((icd->current_fmt->depth + 7) >> 3); | ||
132 | 139 | ||
133 | if (!*count) | 140 | if (!*count) |
134 | *count = 32; | 141 | *count = 32; |
@@ -151,8 +158,10 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf) | |||
151 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 158 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, |
152 | vb, vb->baddr, vb->bsize); | 159 | vb, vb->baddr, vb->bsize); |
153 | 160 | ||
154 | /* This waits until this buffer is out of danger, i.e., until it is no | 161 | /* |
155 | * longer in STATE_QUEUED or STATE_ACTIVE */ | 162 | * This waits until this buffer is out of danger, i.e., until it is no |
163 | * longer in STATE_QUEUED or STATE_ACTIVE | ||
164 | */ | ||
156 | videobuf_waiton(vb, 0, 0); | 165 | videobuf_waiton(vb, 0, 0); |
157 | videobuf_dma_contig_free(vq, vb); | 166 | videobuf_dma_contig_free(vq, vb); |
158 | 167 | ||
@@ -165,6 +174,11 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq, | |||
165 | struct soc_camera_device *icd = vq->priv_data; | 174 | struct soc_camera_device *icd = vq->priv_data; |
166 | struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); | 175 | struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); |
167 | int ret; | 176 | int ret; |
177 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
178 | icd->current_fmt->host_fmt); | ||
179 | |||
180 | if (bytes_per_line < 0) | ||
181 | return bytes_per_line; | ||
168 | 182 | ||
169 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 183 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, |
170 | vb, vb->baddr, vb->bsize); | 184 | vb, vb->baddr, vb->bsize); |
@@ -174,22 +188,24 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq, | |||
174 | 188 | ||
175 | BUG_ON(NULL == icd->current_fmt); | 189 | BUG_ON(NULL == icd->current_fmt); |
176 | 190 | ||
177 | /* I think, in buf_prepare you only have to protect global data, | 191 | /* |
178 | * the actual buffer is yours */ | 192 | * I think, in buf_prepare you only have to protect global data, |
193 | * the actual buffer is yours | ||
194 | */ | ||
179 | buf->inwork = 1; | 195 | buf->inwork = 1; |
180 | 196 | ||
181 | if (buf->fmt != icd->current_fmt || | 197 | if (buf->code != icd->current_fmt->code || |
182 | vb->width != icd->user_width || | 198 | vb->width != icd->user_width || |
183 | vb->height != icd->user_height || | 199 | vb->height != icd->user_height || |
184 | vb->field != field) { | 200 | vb->field != field) { |
185 | buf->fmt = icd->current_fmt; | 201 | buf->code = icd->current_fmt->code; |
186 | vb->width = icd->user_width; | 202 | vb->width = icd->user_width; |
187 | vb->height = icd->user_height; | 203 | vb->height = icd->user_height; |
188 | vb->field = field; | 204 | vb->field = field; |
189 | vb->state = VIDEOBUF_NEEDS_INIT; | 205 | vb->state = VIDEOBUF_NEEDS_INIT; |
190 | } | 206 | } |
191 | 207 | ||
192 | vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); | 208 | vb->size = bytes_per_line * vb->height; |
193 | if (0 != vb->baddr && vb->bsize < vb->size) { | 209 | if (0 != vb->baddr && vb->bsize < vb->size) { |
194 | ret = -EINVAL; | 210 | ret = -EINVAL; |
195 | goto out; | 211 | goto out; |
@@ -381,8 +397,10 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev) | |||
381 | 397 | ||
382 | lcdclk = clk_get_rate(pcdev->clk); | 398 | lcdclk = clk_get_rate(pcdev->clk); |
383 | 399 | ||
384 | /* We verify platform_mclk_10khz != 0, so if anyone breaks it, here | 400 | /* |
385 | * they get a nice Oops */ | 401 | * We verify platform_mclk_10khz != 0, so if anyone breaks it, here |
402 | * they get a nice Oops | ||
403 | */ | ||
386 | div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; | 404 | div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; |
387 | 405 | ||
388 | dev_dbg(pcdev->icd->dev.parent, | 406 | dev_dbg(pcdev->icd->dev.parent, |
@@ -420,8 +438,10 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) | |||
420 | clk_disable(pcdev->clk); | 438 | clk_disable(pcdev->clk); |
421 | } | 439 | } |
422 | 440 | ||
423 | /* The following two functions absolutely depend on the fact, that | 441 | /* |
424 | * there can be only one camera on i.MX1/i.MXL camera sensor interface */ | 442 | * The following two functions absolutely depend on the fact, that |
443 | * there can be only one camera on i.MX1/i.MXL camera sensor interface | ||
444 | */ | ||
425 | static int mx1_camera_add_device(struct soc_camera_device *icd) | 445 | static int mx1_camera_add_device(struct soc_camera_device *icd) |
426 | { | 446 | { |
427 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 447 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
@@ -487,12 +507,10 @@ static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
487 | 507 | ||
488 | /* MX1 supports only 8bit buswidth */ | 508 | /* MX1 supports only 8bit buswidth */ |
489 | common_flags = soc_camera_bus_param_compatible(camera_flags, | 509 | common_flags = soc_camera_bus_param_compatible(camera_flags, |
490 | CSI_BUS_FLAGS); | 510 | CSI_BUS_FLAGS); |
491 | if (!common_flags) | 511 | if (!common_flags) |
492 | return -EINVAL; | 512 | return -EINVAL; |
493 | 513 | ||
494 | icd->buswidth = 8; | ||
495 | |||
496 | /* Make choises, based on platform choice */ | 514 | /* Make choises, based on platform choice */ |
497 | if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && | 515 | if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && |
498 | (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { | 516 | (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { |
@@ -545,7 +563,8 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd, | |||
545 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 563 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
546 | const struct soc_camera_format_xlate *xlate; | 564 | const struct soc_camera_format_xlate *xlate; |
547 | struct v4l2_pix_format *pix = &f->fmt.pix; | 565 | struct v4l2_pix_format *pix = &f->fmt.pix; |
548 | int ret; | 566 | struct v4l2_mbus_framefmt mf; |
567 | int ret, buswidth; | ||
549 | 568 | ||
550 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 569 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
551 | if (!xlate) { | 570 | if (!xlate) { |
@@ -554,12 +573,33 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd, | |||
554 | return -EINVAL; | 573 | return -EINVAL; |
555 | } | 574 | } |
556 | 575 | ||
557 | ret = v4l2_subdev_call(sd, video, s_fmt, f); | 576 | buswidth = xlate->host_fmt->bits_per_sample; |
558 | if (!ret) { | 577 | if (buswidth > 8) { |
559 | icd->buswidth = xlate->buswidth; | 578 | dev_warn(icd->dev.parent, |
560 | icd->current_fmt = xlate->host_fmt; | 579 | "bits-per-sample %d for format %x unsupported\n", |
580 | buswidth, pix->pixelformat); | ||
581 | return -EINVAL; | ||
561 | } | 582 | } |
562 | 583 | ||
584 | mf.width = pix->width; | ||
585 | mf.height = pix->height; | ||
586 | mf.field = pix->field; | ||
587 | mf.colorspace = pix->colorspace; | ||
588 | mf.code = xlate->code; | ||
589 | |||
590 | ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); | ||
591 | if (ret < 0) | ||
592 | return ret; | ||
593 | |||
594 | if (mf.code != xlate->code) | ||
595 | return -EINVAL; | ||
596 | |||
597 | pix->width = mf.width; | ||
598 | pix->height = mf.height; | ||
599 | pix->field = mf.field; | ||
600 | pix->colorspace = mf.colorspace; | ||
601 | icd->current_fmt = xlate; | ||
602 | |||
563 | return ret; | 603 | return ret; |
564 | } | 604 | } |
565 | 605 | ||
@@ -567,10 +607,36 @@ static int mx1_camera_try_fmt(struct soc_camera_device *icd, | |||
567 | struct v4l2_format *f) | 607 | struct v4l2_format *f) |
568 | { | 608 | { |
569 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 609 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
610 | const struct soc_camera_format_xlate *xlate; | ||
611 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
612 | struct v4l2_mbus_framefmt mf; | ||
613 | int ret; | ||
570 | /* TODO: limit to mx1 hardware capabilities */ | 614 | /* TODO: limit to mx1 hardware capabilities */ |
571 | 615 | ||
616 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | ||
617 | if (!xlate) { | ||
618 | dev_warn(icd->dev.parent, "Format %x not found\n", | ||
619 | pix->pixelformat); | ||
620 | return -EINVAL; | ||
621 | } | ||
622 | |||
623 | mf.width = pix->width; | ||
624 | mf.height = pix->height; | ||
625 | mf.field = pix->field; | ||
626 | mf.colorspace = pix->colorspace; | ||
627 | mf.code = xlate->code; | ||
628 | |||
572 | /* limit to sensor capabilities */ | 629 | /* limit to sensor capabilities */ |
573 | return v4l2_subdev_call(sd, video, try_fmt, f); | 630 | ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); |
631 | if (ret < 0) | ||
632 | return ret; | ||
633 | |||
634 | pix->width = mf.width; | ||
635 | pix->height = mf.height; | ||
636 | pix->field = mf.field; | ||
637 | pix->colorspace = mf.colorspace; | ||
638 | |||
639 | return 0; | ||
574 | } | 640 | } |
575 | 641 | ||
576 | static int mx1_camera_reqbufs(struct soc_camera_file *icf, | 642 | static int mx1_camera_reqbufs(struct soc_camera_file *icf, |
@@ -578,10 +644,12 @@ static int mx1_camera_reqbufs(struct soc_camera_file *icf, | |||
578 | { | 644 | { |
579 | int i; | 645 | int i; |
580 | 646 | ||
581 | /* This is for locking debugging only. I removed spinlocks and now I | 647 | /* |
648 | * This is for locking debugging only. I removed spinlocks and now I | ||
582 | * check whether .prepare is ever called on a linked buffer, or whether | 649 | * check whether .prepare is ever called on a linked buffer, or whether |
583 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now | 650 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now |
584 | * it hadn't triggered */ | 651 | * it hadn't triggered |
652 | */ | ||
585 | for (i = 0; i < p->count; i++) { | 653 | for (i = 0; i < p->count; i++) { |
586 | struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i], | 654 | struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i], |
587 | struct mx1_buffer, vb); | 655 | struct mx1_buffer, vb); |
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index 7db82bdf6f3..bd297f567dc 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <media/v4l2-dev.h> | 23 | #include <media/v4l2-dev.h> |
24 | #include <media/videobuf-dma-contig.h> | 24 | #include <media/videobuf-dma-contig.h> |
25 | #include <media/soc_camera.h> | 25 | #include <media/soc_camera.h> |
26 | #include <media/soc_mediabus.h> | ||
26 | 27 | ||
27 | #include <mach/ipu.h> | 28 | #include <mach/ipu.h> |
28 | #include <mach/mx3_camera.h> | 29 | #include <mach/mx3_camera.h> |
@@ -63,7 +64,7 @@ | |||
63 | struct mx3_camera_buffer { | 64 | struct mx3_camera_buffer { |
64 | /* common v4l buffer stuff -- must be first */ | 65 | /* common v4l buffer stuff -- must be first */ |
65 | struct videobuf_buffer vb; | 66 | struct videobuf_buffer vb; |
66 | const struct soc_camera_data_format *fmt; | 67 | enum v4l2_mbus_pixelcode code; |
67 | 68 | ||
68 | /* One descriptot per scatterlist (per frame) */ | 69 | /* One descriptot per scatterlist (per frame) */ |
69 | struct dma_async_tx_descriptor *txd; | 70 | struct dma_async_tx_descriptor *txd; |
@@ -118,8 +119,6 @@ struct dma_chan_request { | |||
118 | enum ipu_channel id; | 119 | enum ipu_channel id; |
119 | }; | 120 | }; |
120 | 121 | ||
121 | static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt); | ||
122 | |||
123 | static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg) | 122 | static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg) |
124 | { | 123 | { |
125 | return __raw_readl(mx3->base + reg); | 124 | return __raw_readl(mx3->base + reg); |
@@ -211,17 +210,16 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, | |||
211 | struct soc_camera_device *icd = vq->priv_data; | 210 | struct soc_camera_device *icd = vq->priv_data; |
212 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 211 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
213 | struct mx3_camera_dev *mx3_cam = ici->priv; | 212 | struct mx3_camera_dev *mx3_cam = ici->priv; |
214 | /* | 213 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, |
215 | * bits-per-pixel (depth) as specified in camera's pixel format does | 214 | icd->current_fmt->host_fmt); |
216 | * not necessarily match what the camera interface writes to RAM, but | 215 | |
217 | * it should be good enough for now. | 216 | if (bytes_per_line < 0) |
218 | */ | 217 | return bytes_per_line; |
219 | unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8); | ||
220 | 218 | ||
221 | if (!mx3_cam->idmac_channel[0]) | 219 | if (!mx3_cam->idmac_channel[0]) |
222 | return -EINVAL; | 220 | return -EINVAL; |
223 | 221 | ||
224 | *size = icd->user_width * icd->user_height * bpp; | 222 | *size = bytes_per_line * icd->user_height; |
225 | 223 | ||
226 | if (!*count) | 224 | if (!*count) |
227 | *count = 32; | 225 | *count = 32; |
@@ -241,21 +239,26 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq, | |||
241 | struct mx3_camera_dev *mx3_cam = ici->priv; | 239 | struct mx3_camera_dev *mx3_cam = ici->priv; |
242 | struct mx3_camera_buffer *buf = | 240 | struct mx3_camera_buffer *buf = |
243 | container_of(vb, struct mx3_camera_buffer, vb); | 241 | container_of(vb, struct mx3_camera_buffer, vb); |
244 | /* current_fmt _must_ always be set */ | 242 | size_t new_size; |
245 | size_t new_size = icd->user_width * icd->user_height * | ||
246 | ((icd->current_fmt->depth + 7) >> 3); | ||
247 | int ret; | 243 | int ret; |
244 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
245 | icd->current_fmt->host_fmt); | ||
246 | |||
247 | if (bytes_per_line < 0) | ||
248 | return bytes_per_line; | ||
249 | |||
250 | new_size = bytes_per_line * icd->user_height; | ||
248 | 251 | ||
249 | /* | 252 | /* |
250 | * I think, in buf_prepare you only have to protect global data, | 253 | * I think, in buf_prepare you only have to protect global data, |
251 | * the actual buffer is yours | 254 | * the actual buffer is yours |
252 | */ | 255 | */ |
253 | 256 | ||
254 | if (buf->fmt != icd->current_fmt || | 257 | if (buf->code != icd->current_fmt->code || |
255 | vb->width != icd->user_width || | 258 | vb->width != icd->user_width || |
256 | vb->height != icd->user_height || | 259 | vb->height != icd->user_height || |
257 | vb->field != field) { | 260 | vb->field != field) { |
258 | buf->fmt = icd->current_fmt; | 261 | buf->code = icd->current_fmt->code; |
259 | vb->width = icd->user_width; | 262 | vb->width = icd->user_width; |
260 | vb->height = icd->user_height; | 263 | vb->height = icd->user_height; |
261 | vb->field = field; | 264 | vb->field = field; |
@@ -348,13 +351,13 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq, | |||
348 | struct dma_async_tx_descriptor *txd = buf->txd; | 351 | struct dma_async_tx_descriptor *txd = buf->txd; |
349 | struct idmac_channel *ichan = to_idmac_chan(txd->chan); | 352 | struct idmac_channel *ichan = to_idmac_chan(txd->chan); |
350 | struct idmac_video_param *video = &ichan->params.video; | 353 | struct idmac_video_param *video = &ichan->params.video; |
351 | const struct soc_camera_data_format *data_fmt = icd->current_fmt; | ||
352 | dma_cookie_t cookie; | 354 | dma_cookie_t cookie; |
355 | u32 fourcc = icd->current_fmt->host_fmt->fourcc; | ||
353 | 356 | ||
354 | BUG_ON(!irqs_disabled()); | 357 | BUG_ON(!irqs_disabled()); |
355 | 358 | ||
356 | /* This is the configuration of one sg-element */ | 359 | /* This is the configuration of one sg-element */ |
357 | video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc); | 360 | video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc); |
358 | video->out_width = icd->user_width; | 361 | video->out_width = icd->user_width; |
359 | video->out_height = icd->user_height; | 362 | video->out_height = icd->user_height; |
360 | video->out_stride = icd->user_width; | 363 | video->out_stride = icd->user_width; |
@@ -564,30 +567,37 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam, | |||
564 | SOCAM_DATA_ACTIVE_HIGH | | 567 | SOCAM_DATA_ACTIVE_HIGH | |
565 | SOCAM_DATA_ACTIVE_LOW; | 568 | SOCAM_DATA_ACTIVE_LOW; |
566 | 569 | ||
567 | /* If requested data width is supported by the platform, use it or any | 570 | /* |
568 | * possible lower value - i.MX31 is smart enough to schift bits */ | 571 | * If requested data width is supported by the platform, use it or any |
572 | * possible lower value - i.MX31 is smart enough to schift bits | ||
573 | */ | ||
574 | if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15) | ||
575 | *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 | | ||
576 | SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; | ||
577 | else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10) | ||
578 | *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 | | ||
579 | SOCAM_DATAWIDTH_4; | ||
580 | else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8) | ||
581 | *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; | ||
582 | else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4) | ||
583 | *flags |= SOCAM_DATAWIDTH_4; | ||
584 | |||
569 | switch (buswidth) { | 585 | switch (buswidth) { |
570 | case 15: | 586 | case 15: |
571 | if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)) | 587 | if (!(*flags & SOCAM_DATAWIDTH_15)) |
572 | return -EINVAL; | 588 | return -EINVAL; |
573 | *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 | | ||
574 | SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; | ||
575 | break; | 589 | break; |
576 | case 10: | 590 | case 10: |
577 | if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)) | 591 | if (!(*flags & SOCAM_DATAWIDTH_10)) |
578 | return -EINVAL; | 592 | return -EINVAL; |
579 | *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 | | ||
580 | SOCAM_DATAWIDTH_4; | ||
581 | break; | 593 | break; |
582 | case 8: | 594 | case 8: |
583 | if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)) | 595 | if (!(*flags & SOCAM_DATAWIDTH_8)) |
584 | return -EINVAL; | 596 | return -EINVAL; |
585 | *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; | ||
586 | break; | 597 | break; |
587 | case 4: | 598 | case 4: |
588 | if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)) | 599 | if (!(*flags & SOCAM_DATAWIDTH_4)) |
589 | return -EINVAL; | 600 | return -EINVAL; |
590 | *flags |= SOCAM_DATAWIDTH_4; | ||
591 | break; | 601 | break; |
592 | default: | 602 | default: |
593 | dev_warn(mx3_cam->soc_host.v4l2_dev.dev, | 603 | dev_warn(mx3_cam->soc_host.v4l2_dev.dev, |
@@ -636,91 +646,92 @@ static bool chan_filter(struct dma_chan *chan, void *arg) | |||
636 | pdata->dma_dev == chan->device->dev; | 646 | pdata->dma_dev == chan->device->dev; |
637 | } | 647 | } |
638 | 648 | ||
639 | static const struct soc_camera_data_format mx3_camera_formats[] = { | 649 | static const struct soc_mbus_pixelfmt mx3_camera_formats[] = { |
640 | { | 650 | { |
641 | .name = "Bayer (sRGB) 8 bit", | 651 | .fourcc = V4L2_PIX_FMT_SBGGR8, |
642 | .depth = 8, | 652 | .name = "Bayer BGGR (sRGB) 8 bit", |
643 | .fourcc = V4L2_PIX_FMT_SBGGR8, | 653 | .bits_per_sample = 8, |
644 | .colorspace = V4L2_COLORSPACE_SRGB, | 654 | .packing = SOC_MBUS_PACKING_NONE, |
655 | .order = SOC_MBUS_ORDER_LE, | ||
645 | }, { | 656 | }, { |
646 | .name = "Monochrome 8 bit", | 657 | .fourcc = V4L2_PIX_FMT_GREY, |
647 | .depth = 8, | 658 | .name = "Monochrome 8 bit", |
648 | .fourcc = V4L2_PIX_FMT_GREY, | 659 | .bits_per_sample = 8, |
649 | .colorspace = V4L2_COLORSPACE_JPEG, | 660 | .packing = SOC_MBUS_PACKING_NONE, |
661 | .order = SOC_MBUS_ORDER_LE, | ||
650 | }, | 662 | }, |
651 | }; | 663 | }; |
652 | 664 | ||
653 | static bool buswidth_supported(struct soc_camera_host *ici, int depth) | 665 | /* This will be corrected as we get more formats */ |
666 | static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) | ||
654 | { | 667 | { |
655 | struct mx3_camera_dev *mx3_cam = ici->priv; | 668 | return fmt->packing == SOC_MBUS_PACKING_NONE || |
656 | 669 | (fmt->bits_per_sample == 8 && | |
657 | switch (depth) { | 670 | fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || |
658 | case 4: | 671 | (fmt->bits_per_sample > 8 && |
659 | return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4); | 672 | fmt->packing == SOC_MBUS_PACKING_EXTEND16); |
660 | case 8: | ||
661 | return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8); | ||
662 | case 10: | ||
663 | return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10); | ||
664 | case 15: | ||
665 | return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15); | ||
666 | } | ||
667 | return false; | ||
668 | } | 673 | } |
669 | 674 | ||
670 | static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, | 675 | static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, |
671 | struct soc_camera_format_xlate *xlate) | 676 | struct soc_camera_format_xlate *xlate) |
672 | { | 677 | { |
673 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 678 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
674 | int formats = 0, buswidth, ret; | 679 | struct device *dev = icd->dev.parent; |
680 | int formats = 0, ret; | ||
681 | enum v4l2_mbus_pixelcode code; | ||
682 | const struct soc_mbus_pixelfmt *fmt; | ||
675 | 683 | ||
676 | buswidth = icd->formats[idx].depth; | 684 | ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); |
685 | if (ret < 0) | ||
686 | /* No more formats */ | ||
687 | return 0; | ||
677 | 688 | ||
678 | if (!buswidth_supported(ici, buswidth)) | 689 | fmt = soc_mbus_get_fmtdesc(code); |
690 | if (!fmt) { | ||
691 | dev_err(icd->dev.parent, | ||
692 | "Invalid format code #%d: %d\n", idx, code); | ||
679 | return 0; | 693 | return 0; |
694 | } | ||
680 | 695 | ||
681 | ret = mx3_camera_try_bus_param(icd, buswidth); | 696 | /* This also checks support for the requested bits-per-sample */ |
697 | ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample); | ||
682 | if (ret < 0) | 698 | if (ret < 0) |
683 | return 0; | 699 | return 0; |
684 | 700 | ||
685 | switch (icd->formats[idx].fourcc) { | 701 | switch (code) { |
686 | case V4L2_PIX_FMT_SGRBG10: | 702 | case V4L2_MBUS_FMT_SBGGR10_1X10: |
687 | formats++; | 703 | formats++; |
688 | if (xlate) { | 704 | if (xlate) { |
689 | xlate->host_fmt = &mx3_camera_formats[0]; | 705 | xlate->host_fmt = &mx3_camera_formats[0]; |
690 | xlate->cam_fmt = icd->formats + idx; | 706 | xlate->code = code; |
691 | xlate->buswidth = buswidth; | ||
692 | xlate++; | 707 | xlate++; |
693 | dev_dbg(icd->dev.parent, | 708 | dev_dbg(dev, "Providing format %s using code %d\n", |
694 | "Providing format %s using %s\n", | 709 | mx3_camera_formats[0].name, code); |
695 | mx3_camera_formats[0].name, | ||
696 | icd->formats[idx].name); | ||
697 | } | 710 | } |
698 | goto passthrough; | 711 | break; |
699 | case V4L2_PIX_FMT_Y16: | 712 | case V4L2_MBUS_FMT_Y10_1X10: |
700 | formats++; | 713 | formats++; |
701 | if (xlate) { | 714 | if (xlate) { |
702 | xlate->host_fmt = &mx3_camera_formats[1]; | 715 | xlate->host_fmt = &mx3_camera_formats[1]; |
703 | xlate->cam_fmt = icd->formats + idx; | 716 | xlate->code = code; |
704 | xlate->buswidth = buswidth; | ||
705 | xlate++; | 717 | xlate++; |
706 | dev_dbg(icd->dev.parent, | 718 | dev_dbg(dev, "Providing format %s using code %d\n", |
707 | "Providing format %s using %s\n", | 719 | mx3_camera_formats[1].name, code); |
708 | mx3_camera_formats[0].name, | ||
709 | icd->formats[idx].name); | ||
710 | } | 720 | } |
721 | break; | ||
711 | default: | 722 | default: |
712 | passthrough: | 723 | if (!mx3_camera_packing_supported(fmt)) |
713 | /* Generic pass-through */ | 724 | return 0; |
714 | formats++; | 725 | } |
715 | if (xlate) { | 726 | |
716 | xlate->host_fmt = icd->formats + idx; | 727 | /* Generic pass-through */ |
717 | xlate->cam_fmt = icd->formats + idx; | 728 | formats++; |
718 | xlate->buswidth = buswidth; | 729 | if (xlate) { |
719 | xlate++; | 730 | xlate->host_fmt = fmt; |
720 | dev_dbg(icd->dev.parent, | 731 | xlate->code = code; |
721 | "Providing format %s in pass-through mode\n", | 732 | xlate++; |
722 | icd->formats[idx].name); | 733 | dev_dbg(dev, "Providing format %x in pass-through mode\n", |
723 | } | 734 | xlate->host_fmt->fourcc); |
724 | } | 735 | } |
725 | 736 | ||
726 | return formats; | 737 | return formats; |
@@ -804,8 +815,7 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd, | |||
804 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 815 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
805 | struct mx3_camera_dev *mx3_cam = ici->priv; | 816 | struct mx3_camera_dev *mx3_cam = ici->priv; |
806 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 817 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
807 | struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE}; | 818 | struct v4l2_mbus_framefmt mf; |
808 | struct v4l2_pix_format *pix = &f.fmt.pix; | ||
809 | int ret; | 819 | int ret; |
810 | 820 | ||
811 | soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096); | 821 | soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096); |
@@ -816,19 +826,19 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd, | |||
816 | return ret; | 826 | return ret; |
817 | 827 | ||
818 | /* The capture device might have changed its output */ | 828 | /* The capture device might have changed its output */ |
819 | ret = v4l2_subdev_call(sd, video, g_fmt, &f); | 829 | ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); |
820 | if (ret < 0) | 830 | if (ret < 0) |
821 | return ret; | 831 | return ret; |
822 | 832 | ||
823 | if (pix->width & 7) { | 833 | if (mf.width & 7) { |
824 | /* Ouch! We can only handle 8-byte aligned width... */ | 834 | /* Ouch! We can only handle 8-byte aligned width... */ |
825 | stride_align(&pix->width); | 835 | stride_align(&mf.width); |
826 | ret = v4l2_subdev_call(sd, video, s_fmt, &f); | 836 | ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); |
827 | if (ret < 0) | 837 | if (ret < 0) |
828 | return ret; | 838 | return ret; |
829 | } | 839 | } |
830 | 840 | ||
831 | if (pix->width != icd->user_width || pix->height != icd->user_height) { | 841 | if (mf.width != icd->user_width || mf.height != icd->user_height) { |
832 | /* | 842 | /* |
833 | * We now know pixel formats and can decide upon DMA-channel(s) | 843 | * We now know pixel formats and can decide upon DMA-channel(s) |
834 | * So far only direct camera-to-memory is supported | 844 | * So far only direct camera-to-memory is supported |
@@ -839,14 +849,14 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd, | |||
839 | return ret; | 849 | return ret; |
840 | } | 850 | } |
841 | 851 | ||
842 | configure_geometry(mx3_cam, pix->width, pix->height); | 852 | configure_geometry(mx3_cam, mf.width, mf.height); |
843 | } | 853 | } |
844 | 854 | ||
845 | dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", | 855 | dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", |
846 | pix->width, pix->height); | 856 | mf.width, mf.height); |
847 | 857 | ||
848 | icd->user_width = pix->width; | 858 | icd->user_width = mf.width; |
849 | icd->user_height = pix->height; | 859 | icd->user_height = mf.height; |
850 | 860 | ||
851 | return ret; | 861 | return ret; |
852 | } | 862 | } |
@@ -859,6 +869,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, | |||
859 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 869 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
860 | const struct soc_camera_format_xlate *xlate; | 870 | const struct soc_camera_format_xlate *xlate; |
861 | struct v4l2_pix_format *pix = &f->fmt.pix; | 871 | struct v4l2_pix_format *pix = &f->fmt.pix; |
872 | struct v4l2_mbus_framefmt mf; | ||
862 | int ret; | 873 | int ret; |
863 | 874 | ||
864 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 875 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
@@ -883,11 +894,24 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd, | |||
883 | 894 | ||
884 | configure_geometry(mx3_cam, pix->width, pix->height); | 895 | configure_geometry(mx3_cam, pix->width, pix->height); |
885 | 896 | ||
886 | ret = v4l2_subdev_call(sd, video, s_fmt, f); | 897 | mf.width = pix->width; |
887 | if (!ret) { | 898 | mf.height = pix->height; |
888 | icd->buswidth = xlate->buswidth; | 899 | mf.field = pix->field; |
889 | icd->current_fmt = xlate->host_fmt; | 900 | mf.colorspace = pix->colorspace; |
890 | } | 901 | mf.code = xlate->code; |
902 | |||
903 | ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); | ||
904 | if (ret < 0) | ||
905 | return ret; | ||
906 | |||
907 | if (mf.code != xlate->code) | ||
908 | return -EINVAL; | ||
909 | |||
910 | pix->width = mf.width; | ||
911 | pix->height = mf.height; | ||
912 | pix->field = mf.field; | ||
913 | pix->colorspace = mf.colorspace; | ||
914 | icd->current_fmt = xlate; | ||
891 | 915 | ||
892 | dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height); | 916 | dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height); |
893 | 917 | ||
@@ -900,8 +924,8 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, | |||
900 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 924 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
901 | const struct soc_camera_format_xlate *xlate; | 925 | const struct soc_camera_format_xlate *xlate; |
902 | struct v4l2_pix_format *pix = &f->fmt.pix; | 926 | struct v4l2_pix_format *pix = &f->fmt.pix; |
927 | struct v4l2_mbus_framefmt mf; | ||
903 | __u32 pixfmt = pix->pixelformat; | 928 | __u32 pixfmt = pix->pixelformat; |
904 | enum v4l2_field field; | ||
905 | int ret; | 929 | int ret; |
906 | 930 | ||
907 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 931 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
@@ -916,23 +940,37 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd, | |||
916 | if (pix->width > 4096) | 940 | if (pix->width > 4096) |
917 | pix->width = 4096; | 941 | pix->width = 4096; |
918 | 942 | ||
919 | pix->bytesperline = pix->width * | 943 | pix->bytesperline = soc_mbus_bytes_per_line(pix->width, |
920 | DIV_ROUND_UP(xlate->host_fmt->depth, 8); | 944 | xlate->host_fmt); |
945 | if (pix->bytesperline < 0) | ||
946 | return pix->bytesperline; | ||
921 | pix->sizeimage = pix->height * pix->bytesperline; | 947 | pix->sizeimage = pix->height * pix->bytesperline; |
922 | 948 | ||
923 | /* camera has to see its format, but the user the original one */ | ||
924 | pix->pixelformat = xlate->cam_fmt->fourcc; | ||
925 | /* limit to sensor capabilities */ | 949 | /* limit to sensor capabilities */ |
926 | ret = v4l2_subdev_call(sd, video, try_fmt, f); | 950 | mf.width = pix->width; |
927 | pix->pixelformat = xlate->host_fmt->fourcc; | 951 | mf.height = pix->height; |
952 | mf.field = pix->field; | ||
953 | mf.colorspace = pix->colorspace; | ||
954 | mf.code = xlate->code; | ||
955 | |||
956 | ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); | ||
957 | if (ret < 0) | ||
958 | return ret; | ||
928 | 959 | ||
929 | field = pix->field; | 960 | pix->width = mf.width; |
961 | pix->height = mf.height; | ||
962 | pix->colorspace = mf.colorspace; | ||
930 | 963 | ||
931 | if (field == V4L2_FIELD_ANY) { | 964 | switch (mf.field) { |
965 | case V4L2_FIELD_ANY: | ||
932 | pix->field = V4L2_FIELD_NONE; | 966 | pix->field = V4L2_FIELD_NONE; |
933 | } else if (field != V4L2_FIELD_NONE) { | 967 | break; |
934 | dev_err(icd->dev.parent, "Field type %d unsupported.\n", field); | 968 | case V4L2_FIELD_NONE: |
935 | return -EINVAL; | 969 | break; |
970 | default: | ||
971 | dev_err(icd->dev.parent, "Field type %d unsupported.\n", | ||
972 | mf.field); | ||
973 | ret = -EINVAL; | ||
936 | } | 974 | } |
937 | 975 | ||
938 | return ret; | 976 | return ret; |
@@ -968,18 +1006,26 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
968 | struct mx3_camera_dev *mx3_cam = ici->priv; | 1006 | struct mx3_camera_dev *mx3_cam = ici->priv; |
969 | unsigned long bus_flags, camera_flags, common_flags; | 1007 | unsigned long bus_flags, camera_flags, common_flags; |
970 | u32 dw, sens_conf; | 1008 | u32 dw, sens_conf; |
971 | int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags); | 1009 | const struct soc_mbus_pixelfmt *fmt; |
1010 | int buswidth; | ||
1011 | int ret; | ||
972 | const struct soc_camera_format_xlate *xlate; | 1012 | const struct soc_camera_format_xlate *xlate; |
973 | struct device *dev = icd->dev.parent; | 1013 | struct device *dev = icd->dev.parent; |
974 | 1014 | ||
1015 | fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); | ||
1016 | if (!fmt) | ||
1017 | return -EINVAL; | ||
1018 | |||
1019 | buswidth = fmt->bits_per_sample; | ||
1020 | ret = test_platform_param(mx3_cam, buswidth, &bus_flags); | ||
1021 | |||
975 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 1022 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
976 | if (!xlate) { | 1023 | if (!xlate) { |
977 | dev_warn(dev, "Format %x not found\n", pixfmt); | 1024 | dev_warn(dev, "Format %x not found\n", pixfmt); |
978 | return -EINVAL; | 1025 | return -EINVAL; |
979 | } | 1026 | } |
980 | 1027 | ||
981 | dev_dbg(dev, "requested bus width %d bit: %d\n", | 1028 | dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret); |
982 | icd->buswidth, ret); | ||
983 | 1029 | ||
984 | if (ret < 0) | 1030 | if (ret < 0) |
985 | return ret; | 1031 | return ret; |
@@ -1027,8 +1073,10 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
1027 | common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; | 1073 | common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; |
1028 | } | 1074 | } |
1029 | 1075 | ||
1030 | /* Make the camera work in widest common mode, we'll take care of | 1076 | /* |
1031 | * the rest */ | 1077 | * Make the camera work in widest common mode, we'll take care of |
1078 | * the rest | ||
1079 | */ | ||
1032 | if (common_flags & SOCAM_DATAWIDTH_15) | 1080 | if (common_flags & SOCAM_DATAWIDTH_15) |
1033 | common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | | 1081 | common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | |
1034 | SOCAM_DATAWIDTH_15; | 1082 | SOCAM_DATAWIDTH_15; |
@@ -1078,7 +1126,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
1078 | sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; | 1126 | sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; |
1079 | 1127 | ||
1080 | /* Just do what we're asked to do */ | 1128 | /* Just do what we're asked to do */ |
1081 | switch (xlate->host_fmt->depth) { | 1129 | switch (xlate->host_fmt->bits_per_sample) { |
1082 | case 4: | 1130 | case 4: |
1083 | dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; | 1131 | dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; |
1084 | break; | 1132 | break; |
@@ -1152,8 +1200,10 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev) | |||
1152 | if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | | 1200 | if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | |
1153 | MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 | | 1201 | MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 | |
1154 | MX3_CAMERA_DATAWIDTH_15))) { | 1202 | MX3_CAMERA_DATAWIDTH_15))) { |
1155 | /* Platform hasn't set available data widths. This is bad. | 1203 | /* |
1156 | * Warn and use a default. */ | 1204 | * Platform hasn't set available data widths. This is bad. |
1205 | * Warn and use a default. | ||
1206 | */ | ||
1157 | dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " | 1207 | dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " |
1158 | "data widths, using default 8 bit\n"); | 1208 | "data widths, using default 8 bit\n"); |
1159 | mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; | 1209 | mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; |
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 5fc4ac0d88f..7400eacb4d6 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c | |||
@@ -1450,12 +1450,11 @@ static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma) | |||
1450 | 1450 | ||
1451 | static int omap24xxcam_open(struct file *file) | 1451 | static int omap24xxcam_open(struct file *file) |
1452 | { | 1452 | { |
1453 | int minor = video_devdata(file)->minor; | ||
1454 | struct omap24xxcam_device *cam = omap24xxcam.priv; | 1453 | struct omap24xxcam_device *cam = omap24xxcam.priv; |
1455 | struct omap24xxcam_fh *fh; | 1454 | struct omap24xxcam_fh *fh; |
1456 | struct v4l2_format format; | 1455 | struct v4l2_format format; |
1457 | 1456 | ||
1458 | if (!cam || !cam->vfd || (cam->vfd->minor != minor)) | 1457 | if (!cam || !cam->vfd) |
1459 | return -ENODEV; | 1458 | return -ENODEV; |
1460 | 1459 | ||
1461 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 1460 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
@@ -1660,7 +1659,6 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s) | |||
1660 | 1659 | ||
1661 | strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name)); | 1660 | strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name)); |
1662 | vfd->fops = &omap24xxcam_fops; | 1661 | vfd->fops = &omap24xxcam_fops; |
1663 | vfd->minor = -1; | ||
1664 | vfd->ioctl_ops = &omap24xxcam_ioctl_fops; | 1662 | vfd->ioctl_ops = &omap24xxcam_ioctl_fops; |
1665 | 1663 | ||
1666 | omap24xxcam_hwinit(cam); | 1664 | omap24xxcam_hwinit(cam); |
@@ -1671,14 +1669,14 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s) | |||
1671 | 1669 | ||
1672 | if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) { | 1670 | if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) { |
1673 | dev_err(cam->dev, "could not register V4L device\n"); | 1671 | dev_err(cam->dev, "could not register V4L device\n"); |
1674 | vfd->minor = -1; | ||
1675 | rval = -EBUSY; | 1672 | rval = -EBUSY; |
1676 | goto err; | 1673 | goto err; |
1677 | } | 1674 | } |
1678 | 1675 | ||
1679 | omap24xxcam_poweron_reset(cam); | 1676 | omap24xxcam_poweron_reset(cam); |
1680 | 1677 | ||
1681 | dev_info(cam->dev, "registered device video%d\n", vfd->minor); | 1678 | dev_info(cam->dev, "registered device %s\n", |
1679 | video_device_node_name(vfd)); | ||
1682 | 1680 | ||
1683 | return 0; | 1681 | return 0; |
1684 | 1682 | ||
@@ -1695,7 +1693,7 @@ static void omap24xxcam_device_unregister(struct v4l2_int_device *s) | |||
1695 | omap24xxcam_sensor_exit(cam); | 1693 | omap24xxcam_sensor_exit(cam); |
1696 | 1694 | ||
1697 | if (cam->vfd) { | 1695 | if (cam->vfd) { |
1698 | if (cam->vfd->minor == -1) { | 1696 | if (!video_is_registered(cam->vfd)) { |
1699 | /* | 1697 | /* |
1700 | * The device was never registered, so release the | 1698 | * The device was never registered, so release the |
1701 | * video_device struct directly. | 1699 | * video_device struct directly. |
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 0bc2cf573c7..e0bce8dc74b 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c | |||
@@ -4674,7 +4674,6 @@ static struct video_device vdev_template = { | |||
4674 | .name = "OV511 USB Camera", | 4674 | .name = "OV511 USB Camera", |
4675 | .fops = &ov511_fops, | 4675 | .fops = &ov511_fops, |
4676 | .release = video_device_release, | 4676 | .release = video_device_release, |
4677 | .minor = -1, | ||
4678 | }; | 4677 | }; |
4679 | 4678 | ||
4680 | /**************************************************************************** | 4679 | /**************************************************************************** |
@@ -5867,8 +5866,8 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5867 | ov511_devused |= 1 << nr; | 5866 | ov511_devused |= 1 << nr; |
5868 | ov->nr = nr; | 5867 | ov->nr = nr; |
5869 | 5868 | ||
5870 | dev_info(&intf->dev, "Device at %s registered to minor %d\n", | 5869 | dev_info(&intf->dev, "Device at %s registered to %s\n", |
5871 | ov->usb_path, ov->vdev->minor); | 5870 | ov->usb_path, video_device_node_name(ov->vdev)); |
5872 | 5871 | ||
5873 | usb_set_intfdata(intf, ov); | 5872 | usb_set_intfdata(intf, ov); |
5874 | if (ov_create_sysfs(ov->vdev)) { | 5873 | if (ov_create_sysfs(ov->vdev)) { |
@@ -5878,13 +5877,13 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
5878 | goto error; | 5877 | goto error; |
5879 | } | 5878 | } |
5880 | 5879 | ||
5881 | mutex_lock(&ov->lock); | 5880 | mutex_unlock(&ov->lock); |
5882 | 5881 | ||
5883 | return 0; | 5882 | return 0; |
5884 | 5883 | ||
5885 | error: | 5884 | error: |
5886 | if (ov->vdev) { | 5885 | if (ov->vdev) { |
5887 | if (-1 == ov->vdev->minor) | 5886 | if (!video_is_registered(ov->vdev)) |
5888 | video_device_release(ov->vdev); | 5887 | video_device_release(ov->vdev); |
5889 | else | 5888 | else |
5890 | video_unregister_device(ov->vdev); | 5889 | video_unregister_device(ov->vdev); |
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 20522933346..3a45e945a52 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <media/v4l2-chip-ident.h> | 24 | #include <media/v4l2-chip-ident.h> |
25 | #include <media/v4l2-subdev.h> | 25 | #include <media/v4l2-subdev.h> |
26 | #include <media/soc_camera.h> | 26 | #include <media/soc_camera.h> |
27 | #include <media/soc_mediabus.h> | ||
27 | #include <media/ov772x.h> | 28 | #include <media/ov772x.h> |
28 | 29 | ||
29 | /* | 30 | /* |
@@ -382,7 +383,8 @@ struct regval_list { | |||
382 | }; | 383 | }; |
383 | 384 | ||
384 | struct ov772x_color_format { | 385 | struct ov772x_color_format { |
385 | const struct soc_camera_data_format *format; | 386 | enum v4l2_mbus_pixelcode code; |
387 | enum v4l2_colorspace colorspace; | ||
386 | u8 dsp3; | 388 | u8 dsp3; |
387 | u8 com3; | 389 | u8 com3; |
388 | u8 com7; | 390 | u8 com7; |
@@ -399,7 +401,7 @@ struct ov772x_win_size { | |||
399 | struct ov772x_priv { | 401 | struct ov772x_priv { |
400 | struct v4l2_subdev subdev; | 402 | struct v4l2_subdev subdev; |
401 | struct ov772x_camera_info *info; | 403 | struct ov772x_camera_info *info; |
402 | const struct ov772x_color_format *fmt; | 404 | const struct ov772x_color_format *cfmt; |
403 | const struct ov772x_win_size *win; | 405 | const struct ov772x_win_size *win; |
404 | int model; | 406 | int model; |
405 | unsigned short flag_vflip:1; | 407 | unsigned short flag_vflip:1; |
@@ -434,93 +436,57 @@ static const struct regval_list ov772x_vga_regs[] = { | |||
434 | }; | 436 | }; |
435 | 437 | ||
436 | /* | 438 | /* |
437 | * supported format list | 439 | * supported color format list |
438 | */ | ||
439 | |||
440 | #define SETFOURCC(type) .name = (#type), .fourcc = (V4L2_PIX_FMT_ ## type) | ||
441 | static const struct soc_camera_data_format ov772x_fmt_lists[] = { | ||
442 | { | ||
443 | SETFOURCC(YUYV), | ||
444 | .depth = 16, | ||
445 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
446 | }, | ||
447 | { | ||
448 | SETFOURCC(YVYU), | ||
449 | .depth = 16, | ||
450 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
451 | }, | ||
452 | { | ||
453 | SETFOURCC(UYVY), | ||
454 | .depth = 16, | ||
455 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
456 | }, | ||
457 | { | ||
458 | SETFOURCC(RGB555), | ||
459 | .depth = 16, | ||
460 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
461 | }, | ||
462 | { | ||
463 | SETFOURCC(RGB555X), | ||
464 | .depth = 16, | ||
465 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
466 | }, | ||
467 | { | ||
468 | SETFOURCC(RGB565), | ||
469 | .depth = 16, | ||
470 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
471 | }, | ||
472 | { | ||
473 | SETFOURCC(RGB565X), | ||
474 | .depth = 16, | ||
475 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
476 | }, | ||
477 | }; | ||
478 | |||
479 | /* | ||
480 | * color format list | ||
481 | */ | 440 | */ |
482 | static const struct ov772x_color_format ov772x_cfmts[] = { | 441 | static const struct ov772x_color_format ov772x_cfmts[] = { |
483 | { | 442 | { |
484 | .format = &ov772x_fmt_lists[0], | 443 | .code = V4L2_MBUS_FMT_YUYV8_2X8_LE, |
485 | .dsp3 = 0x0, | 444 | .colorspace = V4L2_COLORSPACE_JPEG, |
486 | .com3 = SWAP_YUV, | 445 | .dsp3 = 0x0, |
487 | .com7 = OFMT_YUV, | 446 | .com3 = SWAP_YUV, |
447 | .com7 = OFMT_YUV, | ||
488 | }, | 448 | }, |
489 | { | 449 | { |
490 | .format = &ov772x_fmt_lists[1], | 450 | .code = V4L2_MBUS_FMT_YVYU8_2X8_LE, |
491 | .dsp3 = UV_ON, | 451 | .colorspace = V4L2_COLORSPACE_JPEG, |
492 | .com3 = SWAP_YUV, | 452 | .dsp3 = UV_ON, |
493 | .com7 = OFMT_YUV, | 453 | .com3 = SWAP_YUV, |
454 | .com7 = OFMT_YUV, | ||
494 | }, | 455 | }, |
495 | { | 456 | { |
496 | .format = &ov772x_fmt_lists[2], | 457 | .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, |
497 | .dsp3 = 0x0, | 458 | .colorspace = V4L2_COLORSPACE_JPEG, |
498 | .com3 = 0x0, | 459 | .dsp3 = 0x0, |
499 | .com7 = OFMT_YUV, | 460 | .com3 = 0x0, |
461 | .com7 = OFMT_YUV, | ||
500 | }, | 462 | }, |
501 | { | 463 | { |
502 | .format = &ov772x_fmt_lists[3], | 464 | .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, |
503 | .dsp3 = 0x0, | 465 | .colorspace = V4L2_COLORSPACE_SRGB, |
504 | .com3 = SWAP_RGB, | 466 | .dsp3 = 0x0, |
505 | .com7 = FMT_RGB555 | OFMT_RGB, | 467 | .com3 = SWAP_RGB, |
468 | .com7 = FMT_RGB555 | OFMT_RGB, | ||
506 | }, | 469 | }, |
507 | { | 470 | { |
508 | .format = &ov772x_fmt_lists[4], | 471 | .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, |
509 | .dsp3 = 0x0, | 472 | .colorspace = V4L2_COLORSPACE_SRGB, |
510 | .com3 = 0x0, | 473 | .dsp3 = 0x0, |
511 | .com7 = FMT_RGB555 | OFMT_RGB, | 474 | .com3 = 0x0, |
475 | .com7 = FMT_RGB555 | OFMT_RGB, | ||
512 | }, | 476 | }, |
513 | { | 477 | { |
514 | .format = &ov772x_fmt_lists[5], | 478 | .code = V4L2_MBUS_FMT_RGB565_2X8_LE, |
515 | .dsp3 = 0x0, | 479 | .colorspace = V4L2_COLORSPACE_SRGB, |
516 | .com3 = SWAP_RGB, | 480 | .dsp3 = 0x0, |
517 | .com7 = FMT_RGB565 | OFMT_RGB, | 481 | .com3 = SWAP_RGB, |
482 | .com7 = FMT_RGB565 | OFMT_RGB, | ||
518 | }, | 483 | }, |
519 | { | 484 | { |
520 | .format = &ov772x_fmt_lists[6], | 485 | .code = V4L2_MBUS_FMT_RGB565_2X8_BE, |
521 | .dsp3 = 0x0, | 486 | .colorspace = V4L2_COLORSPACE_SRGB, |
522 | .com3 = 0x0, | 487 | .dsp3 = 0x0, |
523 | .com7 = FMT_RGB565 | OFMT_RGB, | 488 | .com3 = 0x0, |
489 | .com7 = FMT_RGB565 | OFMT_RGB, | ||
524 | }, | 490 | }, |
525 | }; | 491 | }; |
526 | 492 | ||
@@ -642,15 +608,15 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) | |||
642 | return 0; | 608 | return 0; |
643 | } | 609 | } |
644 | 610 | ||
645 | if (!priv->win || !priv->fmt) { | 611 | if (!priv->win || !priv->cfmt) { |
646 | dev_err(&client->dev, "norm or win select error\n"); | 612 | dev_err(&client->dev, "norm or win select error\n"); |
647 | return -EPERM; | 613 | return -EPERM; |
648 | } | 614 | } |
649 | 615 | ||
650 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); | 616 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); |
651 | 617 | ||
652 | dev_dbg(&client->dev, "format %s, win %s\n", | 618 | dev_dbg(&client->dev, "format %d, win %s\n", |
653 | priv->fmt->format->name, priv->win->name); | 619 | priv->cfmt->code, priv->win->name); |
654 | 620 | ||
655 | return 0; | 621 | return 0; |
656 | } | 622 | } |
@@ -806,8 +772,8 @@ static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) | |||
806 | return win; | 772 | return win; |
807 | } | 773 | } |
808 | 774 | ||
809 | static int ov772x_set_params(struct i2c_client *client, | 775 | static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height, |
810 | u32 *width, u32 *height, u32 pixfmt) | 776 | enum v4l2_mbus_pixelcode code) |
811 | { | 777 | { |
812 | struct ov772x_priv *priv = to_ov772x(client); | 778 | struct ov772x_priv *priv = to_ov772x(client); |
813 | int ret = -EINVAL; | 779 | int ret = -EINVAL; |
@@ -817,14 +783,14 @@ static int ov772x_set_params(struct i2c_client *client, | |||
817 | /* | 783 | /* |
818 | * select format | 784 | * select format |
819 | */ | 785 | */ |
820 | priv->fmt = NULL; | 786 | priv->cfmt = NULL; |
821 | for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { | 787 | for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { |
822 | if (pixfmt == ov772x_cfmts[i].format->fourcc) { | 788 | if (code == ov772x_cfmts[i].code) { |
823 | priv->fmt = ov772x_cfmts + i; | 789 | priv->cfmt = ov772x_cfmts + i; |
824 | break; | 790 | break; |
825 | } | 791 | } |
826 | } | 792 | } |
827 | if (!priv->fmt) | 793 | if (!priv->cfmt) |
828 | goto ov772x_set_fmt_error; | 794 | goto ov772x_set_fmt_error; |
829 | 795 | ||
830 | /* | 796 | /* |
@@ -894,7 +860,7 @@ static int ov772x_set_params(struct i2c_client *client, | |||
894 | /* | 860 | /* |
895 | * set DSP_CTRL3 | 861 | * set DSP_CTRL3 |
896 | */ | 862 | */ |
897 | val = priv->fmt->dsp3; | 863 | val = priv->cfmt->dsp3; |
898 | if (val) { | 864 | if (val) { |
899 | ret = ov772x_mask_set(client, | 865 | ret = ov772x_mask_set(client, |
900 | DSP_CTRL3, UV_MASK, val); | 866 | DSP_CTRL3, UV_MASK, val); |
@@ -905,7 +871,7 @@ static int ov772x_set_params(struct i2c_client *client, | |||
905 | /* | 871 | /* |
906 | * set COM3 | 872 | * set COM3 |
907 | */ | 873 | */ |
908 | val = priv->fmt->com3; | 874 | val = priv->cfmt->com3; |
909 | if (priv->info->flags & OV772X_FLAG_VFLIP) | 875 | if (priv->info->flags & OV772X_FLAG_VFLIP) |
910 | val |= VFLIP_IMG; | 876 | val |= VFLIP_IMG; |
911 | if (priv->info->flags & OV772X_FLAG_HFLIP) | 877 | if (priv->info->flags & OV772X_FLAG_HFLIP) |
@@ -923,9 +889,9 @@ static int ov772x_set_params(struct i2c_client *client, | |||
923 | /* | 889 | /* |
924 | * set COM7 | 890 | * set COM7 |
925 | */ | 891 | */ |
926 | val = priv->win->com7_bit | priv->fmt->com7; | 892 | val = priv->win->com7_bit | priv->cfmt->com7; |
927 | ret = ov772x_mask_set(client, | 893 | ret = ov772x_mask_set(client, |
928 | COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK), | 894 | COM7, SLCT_MASK | FMT_MASK | OFMT_MASK, |
929 | val); | 895 | val); |
930 | if (ret < 0) | 896 | if (ret < 0) |
931 | goto ov772x_set_fmt_error; | 897 | goto ov772x_set_fmt_error; |
@@ -951,7 +917,7 @@ ov772x_set_fmt_error: | |||
951 | 917 | ||
952 | ov772x_reset(client); | 918 | ov772x_reset(client); |
953 | priv->win = NULL; | 919 | priv->win = NULL; |
954 | priv->fmt = NULL; | 920 | priv->cfmt = NULL; |
955 | 921 | ||
956 | return ret; | 922 | return ret; |
957 | } | 923 | } |
@@ -981,54 +947,79 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
981 | return 0; | 947 | return 0; |
982 | } | 948 | } |
983 | 949 | ||
984 | static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 950 | static int ov772x_g_fmt(struct v4l2_subdev *sd, |
951 | struct v4l2_mbus_framefmt *mf) | ||
985 | { | 952 | { |
986 | struct i2c_client *client = sd->priv; | 953 | struct i2c_client *client = sd->priv; |
987 | struct ov772x_priv *priv = to_ov772x(client); | 954 | struct ov772x_priv *priv = to_ov772x(client); |
988 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
989 | 955 | ||
990 | if (!priv->win || !priv->fmt) { | 956 | if (!priv->win || !priv->cfmt) { |
991 | u32 width = VGA_WIDTH, height = VGA_HEIGHT; | 957 | u32 width = VGA_WIDTH, height = VGA_HEIGHT; |
992 | int ret = ov772x_set_params(client, &width, &height, | 958 | int ret = ov772x_set_params(client, &width, &height, |
993 | V4L2_PIX_FMT_YUYV); | 959 | V4L2_MBUS_FMT_YUYV8_2X8_LE); |
994 | if (ret < 0) | 960 | if (ret < 0) |
995 | return ret; | 961 | return ret; |
996 | } | 962 | } |
997 | 963 | ||
998 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 964 | mf->width = priv->win->width; |
999 | 965 | mf->height = priv->win->height; | |
1000 | pix->width = priv->win->width; | 966 | mf->code = priv->cfmt->code; |
1001 | pix->height = priv->win->height; | 967 | mf->colorspace = priv->cfmt->colorspace; |
1002 | pix->pixelformat = priv->fmt->format->fourcc; | 968 | mf->field = V4L2_FIELD_NONE; |
1003 | pix->colorspace = priv->fmt->format->colorspace; | ||
1004 | pix->field = V4L2_FIELD_NONE; | ||
1005 | 969 | ||
1006 | return 0; | 970 | return 0; |
1007 | } | 971 | } |
1008 | 972 | ||
1009 | static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 973 | static int ov772x_s_fmt(struct v4l2_subdev *sd, |
974 | struct v4l2_mbus_framefmt *mf) | ||
1010 | { | 975 | { |
1011 | struct i2c_client *client = sd->priv; | 976 | struct i2c_client *client = sd->priv; |
1012 | struct v4l2_pix_format *pix = &f->fmt.pix; | 977 | struct ov772x_priv *priv = to_ov772x(client); |
978 | int ret = ov772x_set_params(client, &mf->width, &mf->height, | ||
979 | mf->code); | ||
980 | |||
981 | if (!ret) | ||
982 | mf->colorspace = priv->cfmt->colorspace; | ||
1013 | 983 | ||
1014 | return ov772x_set_params(client, &pix->width, &pix->height, | 984 | return ret; |
1015 | pix->pixelformat); | ||
1016 | } | 985 | } |
1017 | 986 | ||
1018 | static int ov772x_try_fmt(struct v4l2_subdev *sd, | 987 | static int ov772x_try_fmt(struct v4l2_subdev *sd, |
1019 | struct v4l2_format *f) | 988 | struct v4l2_mbus_framefmt *mf) |
1020 | { | 989 | { |
1021 | struct v4l2_pix_format *pix = &f->fmt.pix; | 990 | struct i2c_client *client = sd->priv; |
991 | struct ov772x_priv *priv = to_ov772x(client); | ||
1022 | const struct ov772x_win_size *win; | 992 | const struct ov772x_win_size *win; |
993 | int i; | ||
1023 | 994 | ||
1024 | /* | 995 | /* |
1025 | * select suitable win | 996 | * select suitable win |
1026 | */ | 997 | */ |
1027 | win = ov772x_select_win(pix->width, pix->height); | 998 | win = ov772x_select_win(mf->width, mf->height); |
999 | |||
1000 | mf->width = win->width; | ||
1001 | mf->height = win->height; | ||
1002 | mf->field = V4L2_FIELD_NONE; | ||
1028 | 1003 | ||
1029 | pix->width = win->width; | 1004 | for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) |
1030 | pix->height = win->height; | 1005 | if (mf->code == ov772x_cfmts[i].code) |
1031 | pix->field = V4L2_FIELD_NONE; | 1006 | break; |
1007 | |||
1008 | if (i == ARRAY_SIZE(ov772x_cfmts)) { | ||
1009 | /* Unsupported format requested. Propose either */ | ||
1010 | if (priv->cfmt) { | ||
1011 | /* the current one or */ | ||
1012 | mf->colorspace = priv->cfmt->colorspace; | ||
1013 | mf->code = priv->cfmt->code; | ||
1014 | } else { | ||
1015 | /* the default one */ | ||
1016 | mf->colorspace = ov772x_cfmts[0].colorspace; | ||
1017 | mf->code = ov772x_cfmts[0].code; | ||
1018 | } | ||
1019 | } else { | ||
1020 | /* Also return the colorspace */ | ||
1021 | mf->colorspace = ov772x_cfmts[i].colorspace; | ||
1022 | } | ||
1032 | 1023 | ||
1033 | return 0; | 1024 | return 0; |
1034 | } | 1025 | } |
@@ -1057,9 +1048,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd, | |||
1057 | return -ENODEV; | 1048 | return -ENODEV; |
1058 | } | 1049 | } |
1059 | 1050 | ||
1060 | icd->formats = ov772x_fmt_lists; | ||
1061 | icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists); | ||
1062 | |||
1063 | /* | 1051 | /* |
1064 | * check and show product ID and manufacturer ID | 1052 | * check and show product ID and manufacturer ID |
1065 | */ | 1053 | */ |
@@ -1109,13 +1097,24 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { | |||
1109 | #endif | 1097 | #endif |
1110 | }; | 1098 | }; |
1111 | 1099 | ||
1100 | static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index, | ||
1101 | enum v4l2_mbus_pixelcode *code) | ||
1102 | { | ||
1103 | if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts)) | ||
1104 | return -EINVAL; | ||
1105 | |||
1106 | *code = ov772x_cfmts[index].code; | ||
1107 | return 0; | ||
1108 | } | ||
1109 | |||
1112 | static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { | 1110 | static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { |
1113 | .s_stream = ov772x_s_stream, | 1111 | .s_stream = ov772x_s_stream, |
1114 | .g_fmt = ov772x_g_fmt, | 1112 | .g_mbus_fmt = ov772x_g_fmt, |
1115 | .s_fmt = ov772x_s_fmt, | 1113 | .s_mbus_fmt = ov772x_s_fmt, |
1116 | .try_fmt = ov772x_try_fmt, | 1114 | .try_mbus_fmt = ov772x_try_fmt, |
1117 | .cropcap = ov772x_cropcap, | 1115 | .cropcap = ov772x_cropcap, |
1118 | .g_crop = ov772x_g_crop, | 1116 | .g_crop = ov772x_g_crop, |
1117 | .enum_mbus_fmt = ov772x_enum_fmt, | ||
1119 | }; | 1118 | }; |
1120 | 1119 | ||
1121 | static struct v4l2_subdev_ops ov772x_subdev_ops = { | 1120 | static struct v4l2_subdev_ops ov772x_subdev_ops = { |
@@ -1143,10 +1142,10 @@ static int ov772x_probe(struct i2c_client *client, | |||
1143 | } | 1142 | } |
1144 | 1143 | ||
1145 | icl = to_soc_camera_link(icd); | 1144 | icl = to_soc_camera_link(icd); |
1146 | if (!icl) | 1145 | if (!icl || !icl->priv) |
1147 | return -EINVAL; | 1146 | return -EINVAL; |
1148 | 1147 | ||
1149 | info = container_of(icl, struct ov772x_camera_info, link); | 1148 | info = icl->priv; |
1150 | 1149 | ||
1151 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 1150 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
1152 | dev_err(&adapter->dev, | 1151 | dev_err(&adapter->dev, |
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c index c81ae219288..47bf60ceb7a 100644 --- a/drivers/media/video/ov9640.c +++ b/drivers/media/video/ov9640.c | |||
@@ -154,19 +154,10 @@ static const struct ov9640_reg ov9640_regs_rgb[] = { | |||
154 | { OV9640_MTXS, 0x65 }, | 154 | { OV9640_MTXS, 0x65 }, |
155 | }; | 155 | }; |
156 | 156 | ||
157 | /* | 157 | static enum v4l2_mbus_pixelcode ov9640_codes[] = { |
158 | * TODO: this sensor also supports RGB555 and RGB565 formats, but support for | 158 | V4L2_MBUS_FMT_YUYV8_2X8_BE, |
159 | * them has not yet been sufficiently tested and so it is not included with | 159 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, |
160 | * this version of the driver. To test and debug these formats add two entries | 160 | V4L2_MBUS_FMT_RGB565_2X8_LE, |
161 | * to the below array, see ov722x.c for an example. | ||
162 | */ | ||
163 | static const struct soc_camera_data_format ov9640_fmt_lists[] = { | ||
164 | { | ||
165 | .name = "UYVY", | ||
166 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
167 | .depth = 16, | ||
168 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
169 | }, | ||
170 | }; | 161 | }; |
171 | 162 | ||
172 | static const struct v4l2_queryctrl ov9640_controls[] = { | 163 | static const struct v4l2_queryctrl ov9640_controls[] = { |
@@ -434,20 +425,22 @@ static void ov9640_res_roundup(u32 *width, u32 *height) | |||
434 | } | 425 | } |
435 | 426 | ||
436 | /* Prepare necessary register changes depending on color encoding */ | 427 | /* Prepare necessary register changes depending on color encoding */ |
437 | static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt) | 428 | static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code, |
429 | struct ov9640_reg_alt *alt) | ||
438 | { | 430 | { |
439 | switch (pixfmt) { | 431 | switch (code) { |
440 | case V4L2_PIX_FMT_UYVY: | 432 | default: |
433 | case V4L2_MBUS_FMT_YUYV8_2X8_BE: | ||
441 | alt->com12 = OV9640_COM12_YUV_AVG; | 434 | alt->com12 = OV9640_COM12_YUV_AVG; |
442 | alt->com13 = OV9640_COM13_Y_DELAY_EN | | 435 | alt->com13 = OV9640_COM13_Y_DELAY_EN | |
443 | OV9640_COM13_YUV_DLY(0x01); | 436 | OV9640_COM13_YUV_DLY(0x01); |
444 | break; | 437 | break; |
445 | case V4L2_PIX_FMT_RGB555: | 438 | case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: |
446 | alt->com7 = OV9640_COM7_RGB; | 439 | alt->com7 = OV9640_COM7_RGB; |
447 | alt->com13 = OV9640_COM13_RGB_AVG; | 440 | alt->com13 = OV9640_COM13_RGB_AVG; |
448 | alt->com15 = OV9640_COM15_RGB_555; | 441 | alt->com15 = OV9640_COM15_RGB_555; |
449 | break; | 442 | break; |
450 | case V4L2_PIX_FMT_RGB565: | 443 | case V4L2_MBUS_FMT_RGB565_2X8_LE: |
451 | alt->com7 = OV9640_COM7_RGB; | 444 | alt->com7 = OV9640_COM7_RGB; |
452 | alt->com13 = OV9640_COM13_RGB_AVG; | 445 | alt->com13 = OV9640_COM13_RGB_AVG; |
453 | alt->com15 = OV9640_COM15_RGB_565; | 446 | alt->com15 = OV9640_COM15_RGB_565; |
@@ -456,8 +449,8 @@ static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt) | |||
456 | } | 449 | } |
457 | 450 | ||
458 | /* Setup registers according to resolution and color encoding */ | 451 | /* Setup registers according to resolution and color encoding */ |
459 | static int ov9640_write_regs(struct i2c_client *client, | 452 | static int ov9640_write_regs(struct i2c_client *client, u32 width, |
460 | u32 width, u32 pixfmt, struct ov9640_reg_alt *alts) | 453 | enum v4l2_mbus_pixelcode code, struct ov9640_reg_alt *alts) |
461 | { | 454 | { |
462 | const struct ov9640_reg *ov9640_regs, *matrix_regs; | 455 | const struct ov9640_reg *ov9640_regs, *matrix_regs; |
463 | int ov9640_regs_len, matrix_regs_len; | 456 | int ov9640_regs_len, matrix_regs_len; |
@@ -500,7 +493,7 @@ static int ov9640_write_regs(struct i2c_client *client, | |||
500 | } | 493 | } |
501 | 494 | ||
502 | /* select color matrix configuration for given color encoding */ | 495 | /* select color matrix configuration for given color encoding */ |
503 | if (pixfmt == V4L2_PIX_FMT_UYVY) { | 496 | if (code == V4L2_MBUS_FMT_YUYV8_2X8_BE) { |
504 | matrix_regs = ov9640_regs_yuv; | 497 | matrix_regs = ov9640_regs_yuv; |
505 | matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv); | 498 | matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv); |
506 | } else { | 499 | } else { |
@@ -562,15 +555,17 @@ static int ov9640_prog_dflt(struct i2c_client *client) | |||
562 | } | 555 | } |
563 | 556 | ||
564 | /* set the format we will capture in */ | 557 | /* set the format we will capture in */ |
565 | static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 558 | static int ov9640_s_fmt(struct v4l2_subdev *sd, |
559 | struct v4l2_mbus_framefmt *mf) | ||
566 | { | 560 | { |
567 | struct i2c_client *client = sd->priv; | 561 | struct i2c_client *client = sd->priv; |
568 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
569 | struct ov9640_reg_alt alts = {0}; | 562 | struct ov9640_reg_alt alts = {0}; |
563 | enum v4l2_colorspace cspace; | ||
564 | enum v4l2_mbus_pixelcode code = mf->code; | ||
570 | int ret; | 565 | int ret; |
571 | 566 | ||
572 | ov9640_res_roundup(&pix->width, &pix->height); | 567 | ov9640_res_roundup(&mf->width, &mf->height); |
573 | ov9640_alter_regs(pix->pixelformat, &alts); | 568 | ov9640_alter_regs(mf->code, &alts); |
574 | 569 | ||
575 | ov9640_reset(client); | 570 | ov9640_reset(client); |
576 | 571 | ||
@@ -578,19 +573,57 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |||
578 | if (ret) | 573 | if (ret) |
579 | return ret; | 574 | return ret; |
580 | 575 | ||
581 | return ov9640_write_regs(client, pix->width, pix->pixelformat, &alts); | 576 | switch (code) { |
577 | case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: | ||
578 | case V4L2_MBUS_FMT_RGB565_2X8_LE: | ||
579 | cspace = V4L2_COLORSPACE_SRGB; | ||
580 | break; | ||
581 | default: | ||
582 | code = V4L2_MBUS_FMT_YUYV8_2X8_BE; | ||
583 | case V4L2_MBUS_FMT_YUYV8_2X8_BE: | ||
584 | cspace = V4L2_COLORSPACE_JPEG; | ||
585 | } | ||
586 | |||
587 | ret = ov9640_write_regs(client, mf->width, code, &alts); | ||
588 | if (!ret) { | ||
589 | mf->code = code; | ||
590 | mf->colorspace = cspace; | ||
591 | } | ||
592 | |||
593 | return ret; | ||
582 | } | 594 | } |
583 | 595 | ||
584 | static int ov9640_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 596 | static int ov9640_try_fmt(struct v4l2_subdev *sd, |
597 | struct v4l2_mbus_framefmt *mf) | ||
585 | { | 598 | { |
586 | struct v4l2_pix_format *pix = &f->fmt.pix; | 599 | ov9640_res_roundup(&mf->width, &mf->height); |
587 | 600 | ||
588 | ov9640_res_roundup(&pix->width, &pix->height); | 601 | mf->field = V4L2_FIELD_NONE; |
589 | pix->field = V4L2_FIELD_NONE; | 602 | |
603 | switch (mf->code) { | ||
604 | case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: | ||
605 | case V4L2_MBUS_FMT_RGB565_2X8_LE: | ||
606 | mf->colorspace = V4L2_COLORSPACE_SRGB; | ||
607 | break; | ||
608 | default: | ||
609 | mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE; | ||
610 | case V4L2_MBUS_FMT_YUYV8_2X8_BE: | ||
611 | mf->colorspace = V4L2_COLORSPACE_JPEG; | ||
612 | } | ||
590 | 613 | ||
591 | return 0; | 614 | return 0; |
592 | } | 615 | } |
593 | 616 | ||
617 | static int ov9640_enum_fmt(struct v4l2_subdev *sd, int index, | ||
618 | enum v4l2_mbus_pixelcode *code) | ||
619 | { | ||
620 | if ((unsigned int)index >= ARRAY_SIZE(ov9640_codes)) | ||
621 | return -EINVAL; | ||
622 | |||
623 | *code = ov9640_codes[index]; | ||
624 | return 0; | ||
625 | } | ||
626 | |||
594 | static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 627 | static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
595 | { | 628 | { |
596 | a->c.left = 0; | 629 | a->c.left = 0; |
@@ -637,9 +670,6 @@ static int ov9640_video_probe(struct soc_camera_device *icd, | |||
637 | goto err; | 670 | goto err; |
638 | } | 671 | } |
639 | 672 | ||
640 | icd->formats = ov9640_fmt_lists; | ||
641 | icd->num_formats = ARRAY_SIZE(ov9640_fmt_lists); | ||
642 | |||
643 | /* | 673 | /* |
644 | * check and show product ID and manufacturer ID | 674 | * check and show product ID and manufacturer ID |
645 | */ | 675 | */ |
@@ -702,11 +732,12 @@ static struct v4l2_subdev_core_ops ov9640_core_ops = { | |||
702 | }; | 732 | }; |
703 | 733 | ||
704 | static struct v4l2_subdev_video_ops ov9640_video_ops = { | 734 | static struct v4l2_subdev_video_ops ov9640_video_ops = { |
705 | .s_stream = ov9640_s_stream, | 735 | .s_stream = ov9640_s_stream, |
706 | .s_fmt = ov9640_s_fmt, | 736 | .s_mbus_fmt = ov9640_s_fmt, |
707 | .try_fmt = ov9640_try_fmt, | 737 | .try_mbus_fmt = ov9640_try_fmt, |
708 | .cropcap = ov9640_cropcap, | 738 | .enum_mbus_fmt = ov9640_enum_fmt, |
709 | .g_crop = ov9640_g_crop, | 739 | .cropcap = ov9640_cropcap, |
740 | .g_crop = ov9640_g_crop, | ||
710 | 741 | ||
711 | }; | 742 | }; |
712 | 743 | ||
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 73ec970ca5c..11a2c26399b 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/version.h> | 32 | #include <linux/version.h> |
33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
34 | #include <asm/uaccess.h> | 34 | #include <linux/uaccess.h> |
35 | #include <asm/io.h> | 35 | #include <asm/io.h> |
36 | 36 | ||
37 | #include <linux/videodev2.h> | 37 | #include <linux/videodev2.h> |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 6aa48e0ae73..cc8ddb2d238 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -151,17 +151,6 @@ static struct v4l2_format pvr_format [] = { | |||
151 | }; | 151 | }; |
152 | 152 | ||
153 | 153 | ||
154 | static const char *get_v4l_name(int v4l_type) | ||
155 | { | ||
156 | switch (v4l_type) { | ||
157 | case VFL_TYPE_GRABBER: return "video"; | ||
158 | case VFL_TYPE_RADIO: return "radio"; | ||
159 | case VFL_TYPE_VBI: return "vbi"; | ||
160 | default: return "?"; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | |||
165 | /* | 154 | /* |
166 | * pvr_ioctl() | 155 | * pvr_ioctl() |
167 | * | 156 | * |
@@ -891,10 +880,8 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
891 | 880 | ||
892 | static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) | 881 | static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) |
893 | { | 882 | { |
894 | int num = dip->devbase.num; | ||
895 | struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw; | 883 | struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw; |
896 | enum pvr2_config cfg = dip->config; | 884 | enum pvr2_config cfg = dip->config; |
897 | int v4l_type = dip->v4l_type; | ||
898 | 885 | ||
899 | pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1); | 886 | pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1); |
900 | 887 | ||
@@ -906,8 +893,8 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) | |||
906 | are gone. */ | 893 | are gone. */ |
907 | video_unregister_device(&dip->devbase); | 894 | video_unregister_device(&dip->devbase); |
908 | 895 | ||
909 | printk(KERN_INFO "pvrusb2: unregistered device %s%u [%s]\n", | 896 | printk(KERN_INFO "pvrusb2: unregistered device %s [%s]\n", |
910 | get_v4l_name(v4l_type), num, | 897 | video_device_node_name(&dip->devbase), |
911 | pvr2_config_get_name(cfg)); | 898 | pvr2_config_get_name(cfg)); |
912 | 899 | ||
913 | } | 900 | } |
@@ -1317,8 +1304,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, | |||
1317 | ": Failed to register pvrusb2 v4l device\n"); | 1304 | ": Failed to register pvrusb2 v4l device\n"); |
1318 | } | 1305 | } |
1319 | 1306 | ||
1320 | printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n", | 1307 | printk(KERN_INFO "pvrusb2: registered device %s [%s]\n", |
1321 | get_v4l_name(dip->v4l_type), dip->devbase.num, | 1308 | video_device_node_name(&dip->devbase), |
1322 | pvr2_config_get_name(dip->config)); | 1309 | pvr2_config_get_name(dip->config)); |
1323 | 1310 | ||
1324 | pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, | 1311 | pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 89b620f6db7..aea7e224cef 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -169,7 +169,6 @@ static struct video_device pwc_template = { | |||
169 | .name = "Philips Webcam", /* Filled in later */ | 169 | .name = "Philips Webcam", /* Filled in later */ |
170 | .release = video_device_release, | 170 | .release = video_device_release, |
171 | .fops = &pwc_fops, | 171 | .fops = &pwc_fops, |
172 | .minor = -1, | ||
173 | }; | 172 | }; |
174 | 173 | ||
175 | /***************************************************************************/ | 174 | /***************************************************************************/ |
@@ -1807,7 +1806,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1807 | goto err_video_release; | 1806 | goto err_video_release; |
1808 | } | 1807 | } |
1809 | 1808 | ||
1810 | PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->num); | 1809 | PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev)); |
1811 | 1810 | ||
1812 | /* occupy slot */ | 1811 | /* occupy slot */ |
1813 | if (hint < MAX_DEV_HINTS) | 1812 | if (hint < MAX_DEV_HINTS) |
@@ -1948,7 +1947,9 @@ MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, | |||
1948 | MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); | 1947 | MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); |
1949 | MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); | 1948 | MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve"); |
1950 | MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); | 1949 | MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers"); |
1950 | #ifdef CONFIG_USB_PWC_DEBUG | ||
1951 | MODULE_PARM_DESC(trace, "For debugging purposes"); | 1951 | MODULE_PARM_DESC(trace, "For debugging purposes"); |
1952 | #endif | ||
1952 | MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); | 1953 | MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off"); |
1953 | MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); | 1954 | MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); |
1954 | MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); | 1955 | MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 51b683c63b7..294f860ce2b 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <media/v4l2-dev.h> | 32 | #include <media/v4l2-dev.h> |
33 | #include <media/videobuf-dma-sg.h> | 33 | #include <media/videobuf-dma-sg.h> |
34 | #include <media/soc_camera.h> | 34 | #include <media/soc_camera.h> |
35 | #include <media/soc_mediabus.h> | ||
35 | 36 | ||
36 | #include <linux/videodev2.h> | 37 | #include <linux/videodev2.h> |
37 | 38 | ||
@@ -183,23 +184,21 @@ struct pxa_cam_dma { | |||
183 | /* buffer for one video frame */ | 184 | /* buffer for one video frame */ |
184 | struct pxa_buffer { | 185 | struct pxa_buffer { |
185 | /* common v4l buffer stuff -- must be first */ | 186 | /* common v4l buffer stuff -- must be first */ |
186 | struct videobuf_buffer vb; | 187 | struct videobuf_buffer vb; |
187 | 188 | enum v4l2_mbus_pixelcode code; | |
188 | const struct soc_camera_data_format *fmt; | ||
189 | |||
190 | /* our descriptor lists for Y, U and V channels */ | 189 | /* our descriptor lists for Y, U and V channels */ |
191 | struct pxa_cam_dma dmas[3]; | 190 | struct pxa_cam_dma dmas[3]; |
192 | 191 | int inwork; | |
193 | int inwork; | 192 | enum pxa_camera_active_dma active_dma; |
194 | |||
195 | enum pxa_camera_active_dma active_dma; | ||
196 | }; | 193 | }; |
197 | 194 | ||
198 | struct pxa_camera_dev { | 195 | struct pxa_camera_dev { |
199 | struct soc_camera_host soc_host; | 196 | struct soc_camera_host soc_host; |
200 | /* PXA27x is only supposed to handle one camera on its Quick Capture | 197 | /* |
198 | * PXA27x is only supposed to handle one camera on its Quick Capture | ||
201 | * interface. If anyone ever builds hardware to enable more than | 199 | * interface. If anyone ever builds hardware to enable more than |
202 | * one camera, they will have to modify this driver too */ | 200 | * one camera, they will have to modify this driver too |
201 | */ | ||
203 | struct soc_camera_device *icd; | 202 | struct soc_camera_device *icd; |
204 | struct clk *clk; | 203 | struct clk *clk; |
205 | 204 | ||
@@ -241,11 +240,15 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, | |||
241 | unsigned int *size) | 240 | unsigned int *size) |
242 | { | 241 | { |
243 | struct soc_camera_device *icd = vq->priv_data; | 242 | struct soc_camera_device *icd = vq->priv_data; |
243 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
244 | icd->current_fmt->host_fmt); | ||
245 | |||
246 | if (bytes_per_line < 0) | ||
247 | return bytes_per_line; | ||
244 | 248 | ||
245 | dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size); | 249 | dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size); |
246 | 250 | ||
247 | *size = roundup(icd->user_width * icd->user_height * | 251 | *size = bytes_per_line * icd->user_height; |
248 | ((icd->current_fmt->depth + 7) >> 3), 8); | ||
249 | 252 | ||
250 | if (0 == *count) | 253 | if (0 == *count) |
251 | *count = 32; | 254 | *count = 32; |
@@ -267,8 +270,10 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) | |||
267 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 270 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, |
268 | &buf->vb, buf->vb.baddr, buf->vb.bsize); | 271 | &buf->vb, buf->vb.baddr, buf->vb.bsize); |
269 | 272 | ||
270 | /* This waits until this buffer is out of danger, i.e., until it is no | 273 | /* |
271 | * longer in STATE_QUEUED or STATE_ACTIVE */ | 274 | * This waits until this buffer is out of danger, i.e., until it is no |
275 | * longer in STATE_QUEUED or STATE_ACTIVE | ||
276 | */ | ||
272 | videobuf_waiton(&buf->vb, 0, 0); | 277 | videobuf_waiton(&buf->vb, 0, 0); |
273 | videobuf_dma_unmap(vq, dma); | 278 | videobuf_dma_unmap(vq, dma); |
274 | videobuf_dma_free(dma); | 279 | videobuf_dma_free(dma); |
@@ -429,6 +434,11 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
429 | struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); | 434 | struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); |
430 | int ret; | 435 | int ret; |
431 | int size_y, size_u = 0, size_v = 0; | 436 | int size_y, size_u = 0, size_v = 0; |
437 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
438 | icd->current_fmt->host_fmt); | ||
439 | |||
440 | if (bytes_per_line < 0) | ||
441 | return bytes_per_line; | ||
432 | 442 | ||
433 | dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 443 | dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, |
434 | vb, vb->baddr, vb->bsize); | 444 | vb, vb->baddr, vb->bsize); |
@@ -437,29 +447,33 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, | |||
437 | WARN_ON(!list_empty(&vb->queue)); | 447 | WARN_ON(!list_empty(&vb->queue)); |
438 | 448 | ||
439 | #ifdef DEBUG | 449 | #ifdef DEBUG |
440 | /* This can be useful if you want to see if we actually fill | 450 | /* |
441 | * the buffer with something */ | 451 | * This can be useful if you want to see if we actually fill |
452 | * the buffer with something | ||
453 | */ | ||
442 | memset((void *)vb->baddr, 0xaa, vb->bsize); | 454 | memset((void *)vb->baddr, 0xaa, vb->bsize); |
443 | #endif | 455 | #endif |
444 | 456 | ||
445 | BUG_ON(NULL == icd->current_fmt); | 457 | BUG_ON(NULL == icd->current_fmt); |
446 | 458 | ||
447 | /* I think, in buf_prepare you only have to protect global data, | 459 | /* |
448 | * the actual buffer is yours */ | 460 | * I think, in buf_prepare you only have to protect global data, |
461 | * the actual buffer is yours | ||
462 | */ | ||
449 | buf->inwork = 1; | 463 | buf->inwork = 1; |
450 | 464 | ||
451 | if (buf->fmt != icd->current_fmt || | 465 | if (buf->code != icd->current_fmt->code || |
452 | vb->width != icd->user_width || | 466 | vb->width != icd->user_width || |
453 | vb->height != icd->user_height || | 467 | vb->height != icd->user_height || |
454 | vb->field != field) { | 468 | vb->field != field) { |
455 | buf->fmt = icd->current_fmt; | 469 | buf->code = icd->current_fmt->code; |
456 | vb->width = icd->user_width; | 470 | vb->width = icd->user_width; |
457 | vb->height = icd->user_height; | 471 | vb->height = icd->user_height; |
458 | vb->field = field; | 472 | vb->field = field; |
459 | vb->state = VIDEOBUF_NEEDS_INIT; | 473 | vb->state = VIDEOBUF_NEEDS_INIT; |
460 | } | 474 | } |
461 | 475 | ||
462 | vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); | 476 | vb->size = bytes_per_line * vb->height; |
463 | if (0 != vb->baddr && vb->bsize < vb->size) { | 477 | if (0 != vb->baddr && vb->bsize < vb->size) { |
464 | ret = -EINVAL; | 478 | ret = -EINVAL; |
465 | goto out; | 479 | goto out; |
@@ -834,8 +848,10 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q, | |||
834 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 848 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
835 | struct pxa_camera_dev *pcdev = ici->priv; | 849 | struct pxa_camera_dev *pcdev = ici->priv; |
836 | 850 | ||
837 | /* We must pass NULL as dev pointer, then all pci_* dma operations | 851 | /* |
838 | * transform to normal dma_* ones. */ | 852 | * We must pass NULL as dev pointer, then all pci_* dma operations |
853 | * transform to normal dma_* ones. | ||
854 | */ | ||
839 | videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, | 855 | videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, |
840 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 856 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
841 | sizeof(struct pxa_buffer), icd); | 857 | sizeof(struct pxa_buffer), icd); |
@@ -1051,11 +1067,18 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, | |||
1051 | { | 1067 | { |
1052 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 1068 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
1053 | struct pxa_camera_dev *pcdev = ici->priv; | 1069 | struct pxa_camera_dev *pcdev = ici->priv; |
1070 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1054 | unsigned long dw, bpp; | 1071 | unsigned long dw, bpp; |
1055 | u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0; | 1072 | u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0, y_skip_top; |
1073 | int ret = v4l2_subdev_call(sd, sensor, g_skip_top_lines, &y_skip_top); | ||
1074 | |||
1075 | if (ret < 0) | ||
1076 | y_skip_top = 0; | ||
1056 | 1077 | ||
1057 | /* Datawidth is now guaranteed to be equal to one of the three values. | 1078 | /* |
1058 | * We fix bit-per-pixel equal to data-width... */ | 1079 | * Datawidth is now guaranteed to be equal to one of the three values. |
1080 | * We fix bit-per-pixel equal to data-width... | ||
1081 | */ | ||
1059 | switch (flags & SOCAM_DATAWIDTH_MASK) { | 1082 | switch (flags & SOCAM_DATAWIDTH_MASK) { |
1060 | case SOCAM_DATAWIDTH_10: | 1083 | case SOCAM_DATAWIDTH_10: |
1061 | dw = 4; | 1084 | dw = 4; |
@@ -1066,8 +1089,10 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, | |||
1066 | bpp = 0x20; | 1089 | bpp = 0x20; |
1067 | break; | 1090 | break; |
1068 | default: | 1091 | default: |
1069 | /* Actually it can only be 8 now, | 1092 | /* |
1070 | * default is just to silence compiler warnings */ | 1093 | * Actually it can only be 8 now, |
1094 | * default is just to silence compiler warnings | ||
1095 | */ | ||
1071 | case SOCAM_DATAWIDTH_8: | 1096 | case SOCAM_DATAWIDTH_8: |
1072 | dw = 2; | 1097 | dw = 2; |
1073 | bpp = 0; | 1098 | bpp = 0; |
@@ -1118,7 +1143,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, | |||
1118 | 1143 | ||
1119 | cicr2 = 0; | 1144 | cicr2 = 0; |
1120 | cicr3 = CICR3_LPF_VAL(icd->user_height - 1) | | 1145 | cicr3 = CICR3_LPF_VAL(icd->user_height - 1) | |
1121 | CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); | 1146 | CICR3_BFW_VAL(min((u32)255, y_skip_top)); |
1122 | cicr4 |= pcdev->mclk_divisor; | 1147 | cicr4 |= pcdev->mclk_divisor; |
1123 | 1148 | ||
1124 | __raw_writel(cicr1, pcdev->base + CICR1); | 1149 | __raw_writel(cicr1, pcdev->base + CICR1); |
@@ -1138,9 +1163,15 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
1138 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 1163 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
1139 | struct pxa_camera_dev *pcdev = ici->priv; | 1164 | struct pxa_camera_dev *pcdev = ici->priv; |
1140 | unsigned long bus_flags, camera_flags, common_flags; | 1165 | unsigned long bus_flags, camera_flags, common_flags; |
1141 | int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags); | 1166 | const struct soc_mbus_pixelfmt *fmt; |
1167 | int ret; | ||
1142 | struct pxa_cam *cam = icd->host_priv; | 1168 | struct pxa_cam *cam = icd->host_priv; |
1143 | 1169 | ||
1170 | fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); | ||
1171 | if (!fmt) | ||
1172 | return -EINVAL; | ||
1173 | |||
1174 | ret = test_platform_param(pcdev, fmt->bits_per_sample, &bus_flags); | ||
1144 | if (ret < 0) | 1175 | if (ret < 0) |
1145 | return ret; | 1176 | return ret; |
1146 | 1177 | ||
@@ -1204,59 +1235,49 @@ static int pxa_camera_try_bus_param(struct soc_camera_device *icd, | |||
1204 | return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; | 1235 | return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; |
1205 | } | 1236 | } |
1206 | 1237 | ||
1207 | static const struct soc_camera_data_format pxa_camera_formats[] = { | 1238 | static const struct soc_mbus_pixelfmt pxa_camera_formats[] = { |
1208 | { | 1239 | { |
1209 | .name = "Planar YUV422 16 bit", | 1240 | .fourcc = V4L2_PIX_FMT_YUV422P, |
1210 | .depth = 16, | 1241 | .name = "Planar YUV422 16 bit", |
1211 | .fourcc = V4L2_PIX_FMT_YUV422P, | 1242 | .bits_per_sample = 8, |
1212 | .colorspace = V4L2_COLORSPACE_JPEG, | 1243 | .packing = SOC_MBUS_PACKING_2X8_PADHI, |
1244 | .order = SOC_MBUS_ORDER_LE, | ||
1213 | }, | 1245 | }, |
1214 | }; | 1246 | }; |
1215 | 1247 | ||
1216 | static bool buswidth_supported(struct soc_camera_device *icd, int depth) | 1248 | /* This will be corrected as we get more formats */ |
1249 | static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) | ||
1217 | { | 1250 | { |
1218 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 1251 | return fmt->packing == SOC_MBUS_PACKING_NONE || |
1219 | struct pxa_camera_dev *pcdev = ici->priv; | 1252 | (fmt->bits_per_sample == 8 && |
1220 | 1253 | fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || | |
1221 | switch (depth) { | 1254 | (fmt->bits_per_sample > 8 && |
1222 | case 8: | 1255 | fmt->packing == SOC_MBUS_PACKING_EXTEND16); |
1223 | return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8); | ||
1224 | case 9: | ||
1225 | return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9); | ||
1226 | case 10: | ||
1227 | return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10); | ||
1228 | } | ||
1229 | return false; | ||
1230 | } | ||
1231 | |||
1232 | static int required_buswidth(const struct soc_camera_data_format *fmt) | ||
1233 | { | ||
1234 | switch (fmt->fourcc) { | ||
1235 | case V4L2_PIX_FMT_UYVY: | ||
1236 | case V4L2_PIX_FMT_VYUY: | ||
1237 | case V4L2_PIX_FMT_YUYV: | ||
1238 | case V4L2_PIX_FMT_YVYU: | ||
1239 | case V4L2_PIX_FMT_RGB565: | ||
1240 | case V4L2_PIX_FMT_RGB555: | ||
1241 | return 8; | ||
1242 | default: | ||
1243 | return fmt->depth; | ||
1244 | } | ||
1245 | } | 1256 | } |
1246 | 1257 | ||
1247 | static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, | 1258 | static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, |
1248 | struct soc_camera_format_xlate *xlate) | 1259 | struct soc_camera_format_xlate *xlate) |
1249 | { | 1260 | { |
1261 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
1250 | struct device *dev = icd->dev.parent; | 1262 | struct device *dev = icd->dev.parent; |
1251 | int formats = 0, buswidth, ret; | 1263 | int formats = 0, ret; |
1252 | struct pxa_cam *cam; | 1264 | struct pxa_cam *cam; |
1265 | enum v4l2_mbus_pixelcode code; | ||
1266 | const struct soc_mbus_pixelfmt *fmt; | ||
1253 | 1267 | ||
1254 | buswidth = required_buswidth(icd->formats + idx); | 1268 | ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); |
1269 | if (ret < 0) | ||
1270 | /* No more formats */ | ||
1271 | return 0; | ||
1255 | 1272 | ||
1256 | if (!buswidth_supported(icd, buswidth)) | 1273 | fmt = soc_mbus_get_fmtdesc(code); |
1274 | if (!fmt) { | ||
1275 | dev_err(dev, "Invalid format code #%d: %d\n", idx, code); | ||
1257 | return 0; | 1276 | return 0; |
1277 | } | ||
1258 | 1278 | ||
1259 | ret = pxa_camera_try_bus_param(icd, buswidth); | 1279 | /* This also checks support for the requested bits-per-sample */ |
1280 | ret = pxa_camera_try_bus_param(icd, fmt->bits_per_sample); | ||
1260 | if (ret < 0) | 1281 | if (ret < 0) |
1261 | return 0; | 1282 | return 0; |
1262 | 1283 | ||
@@ -1270,45 +1291,40 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, | |||
1270 | cam = icd->host_priv; | 1291 | cam = icd->host_priv; |
1271 | } | 1292 | } |
1272 | 1293 | ||
1273 | switch (icd->formats[idx].fourcc) { | 1294 | switch (code) { |
1274 | case V4L2_PIX_FMT_UYVY: | 1295 | case V4L2_MBUS_FMT_YUYV8_2X8_BE: |
1275 | formats++; | 1296 | formats++; |
1276 | if (xlate) { | 1297 | if (xlate) { |
1277 | xlate->host_fmt = &pxa_camera_formats[0]; | 1298 | xlate->host_fmt = &pxa_camera_formats[0]; |
1278 | xlate->cam_fmt = icd->formats + idx; | 1299 | xlate->code = code; |
1279 | xlate->buswidth = buswidth; | ||
1280 | xlate++; | 1300 | xlate++; |
1281 | dev_dbg(dev, "Providing format %s using %s\n", | 1301 | dev_dbg(dev, "Providing format %s using code %d\n", |
1282 | pxa_camera_formats[0].name, | 1302 | pxa_camera_formats[0].name, code); |
1283 | icd->formats[idx].name); | ||
1284 | } | 1303 | } |
1285 | case V4L2_PIX_FMT_VYUY: | 1304 | case V4L2_MBUS_FMT_YVYU8_2X8_BE: |
1286 | case V4L2_PIX_FMT_YUYV: | 1305 | case V4L2_MBUS_FMT_YUYV8_2X8_LE: |
1287 | case V4L2_PIX_FMT_YVYU: | 1306 | case V4L2_MBUS_FMT_YVYU8_2X8_LE: |
1288 | case V4L2_PIX_FMT_RGB565: | 1307 | case V4L2_MBUS_FMT_RGB565_2X8_LE: |
1289 | case V4L2_PIX_FMT_RGB555: | 1308 | case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: |
1290 | formats++; | 1309 | if (xlate) |
1291 | if (xlate) { | ||
1292 | xlate->host_fmt = icd->formats + idx; | ||
1293 | xlate->cam_fmt = icd->formats + idx; | ||
1294 | xlate->buswidth = buswidth; | ||
1295 | xlate++; | ||
1296 | dev_dbg(dev, "Providing format %s packed\n", | 1310 | dev_dbg(dev, "Providing format %s packed\n", |
1297 | icd->formats[idx].name); | 1311 | fmt->name); |
1298 | } | ||
1299 | break; | 1312 | break; |
1300 | default: | 1313 | default: |
1301 | /* Generic pass-through */ | 1314 | if (!pxa_camera_packing_supported(fmt)) |
1302 | formats++; | 1315 | return 0; |
1303 | if (xlate) { | 1316 | if (xlate) |
1304 | xlate->host_fmt = icd->formats + idx; | ||
1305 | xlate->cam_fmt = icd->formats + idx; | ||
1306 | xlate->buswidth = icd->formats[idx].depth; | ||
1307 | xlate++; | ||
1308 | dev_dbg(dev, | 1317 | dev_dbg(dev, |
1309 | "Providing format %s in pass-through mode\n", | 1318 | "Providing format %s in pass-through mode\n", |
1310 | icd->formats[idx].name); | 1319 | fmt->name); |
1311 | } | 1320 | } |
1321 | |||
1322 | /* Generic pass-through */ | ||
1323 | formats++; | ||
1324 | if (xlate) { | ||
1325 | xlate->host_fmt = fmt; | ||
1326 | xlate->code = code; | ||
1327 | xlate++; | ||
1312 | } | 1328 | } |
1313 | 1329 | ||
1314 | return formats; | 1330 | return formats; |
@@ -1320,11 +1336,11 @@ static void pxa_camera_put_formats(struct soc_camera_device *icd) | |||
1320 | icd->host_priv = NULL; | 1336 | icd->host_priv = NULL; |
1321 | } | 1337 | } |
1322 | 1338 | ||
1323 | static int pxa_camera_check_frame(struct v4l2_pix_format *pix) | 1339 | static int pxa_camera_check_frame(u32 width, u32 height) |
1324 | { | 1340 | { |
1325 | /* limit to pxa hardware capabilities */ | 1341 | /* limit to pxa hardware capabilities */ |
1326 | return pix->height < 32 || pix->height > 2048 || pix->width < 48 || | 1342 | return height < 32 || height > 2048 || width < 48 || width > 2048 || |
1327 | pix->width > 2048 || (pix->width & 0x01); | 1343 | (width & 0x01); |
1328 | } | 1344 | } |
1329 | 1345 | ||
1330 | static int pxa_camera_set_crop(struct soc_camera_device *icd, | 1346 | static int pxa_camera_set_crop(struct soc_camera_device *icd, |
@@ -1339,9 +1355,9 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, | |||
1339 | .master_clock = pcdev->mclk, | 1355 | .master_clock = pcdev->mclk, |
1340 | .pixel_clock_max = pcdev->ciclk / 4, | 1356 | .pixel_clock_max = pcdev->ciclk / 4, |
1341 | }; | 1357 | }; |
1342 | struct v4l2_format f; | 1358 | struct v4l2_mbus_framefmt mf; |
1343 | struct v4l2_pix_format *pix = &f.fmt.pix, pix_tmp; | ||
1344 | struct pxa_cam *cam = icd->host_priv; | 1359 | struct pxa_cam *cam = icd->host_priv; |
1360 | u32 fourcc = icd->current_fmt->host_fmt->fourcc; | ||
1345 | int ret; | 1361 | int ret; |
1346 | 1362 | ||
1347 | /* If PCLK is used to latch data from the sensor, check sense */ | 1363 | /* If PCLK is used to latch data from the sensor, check sense */ |
@@ -1358,27 +1374,23 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, | |||
1358 | return ret; | 1374 | return ret; |
1359 | } | 1375 | } |
1360 | 1376 | ||
1361 | f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1377 | ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); |
1362 | |||
1363 | ret = v4l2_subdev_call(sd, video, g_fmt, &f); | ||
1364 | if (ret < 0) | 1378 | if (ret < 0) |
1365 | return ret; | 1379 | return ret; |
1366 | 1380 | ||
1367 | pix_tmp = *pix; | 1381 | if (pxa_camera_check_frame(mf.width, mf.height)) { |
1368 | if (pxa_camera_check_frame(pix)) { | ||
1369 | /* | 1382 | /* |
1370 | * Camera cropping produced a frame beyond our capabilities. | 1383 | * Camera cropping produced a frame beyond our capabilities. |
1371 | * FIXME: just extract a subframe, that we can process. | 1384 | * FIXME: just extract a subframe, that we can process. |
1372 | */ | 1385 | */ |
1373 | v4l_bound_align_image(&pix->width, 48, 2048, 1, | 1386 | v4l_bound_align_image(&mf.width, 48, 2048, 1, |
1374 | &pix->height, 32, 2048, 0, | 1387 | &mf.height, 32, 2048, 0, |
1375 | icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? | 1388 | fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0); |
1376 | 4 : 0); | 1389 | ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); |
1377 | ret = v4l2_subdev_call(sd, video, s_fmt, &f); | ||
1378 | if (ret < 0) | 1390 | if (ret < 0) |
1379 | return ret; | 1391 | return ret; |
1380 | 1392 | ||
1381 | if (pxa_camera_check_frame(pix)) { | 1393 | if (pxa_camera_check_frame(mf.width, mf.height)) { |
1382 | dev_warn(icd->dev.parent, | 1394 | dev_warn(icd->dev.parent, |
1383 | "Inconsistent state. Use S_FMT to repair\n"); | 1395 | "Inconsistent state. Use S_FMT to repair\n"); |
1384 | return -EINVAL; | 1396 | return -EINVAL; |
@@ -1395,10 +1407,10 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, | |||
1395 | recalculate_fifo_timeout(pcdev, sense.pixel_clock); | 1407 | recalculate_fifo_timeout(pcdev, sense.pixel_clock); |
1396 | } | 1408 | } |
1397 | 1409 | ||
1398 | icd->user_width = pix->width; | 1410 | icd->user_width = mf.width; |
1399 | icd->user_height = pix->height; | 1411 | icd->user_height = mf.height; |
1400 | 1412 | ||
1401 | pxa_camera_setup_cicr(icd, cam->flags, icd->current_fmt->fourcc); | 1413 | pxa_camera_setup_cicr(icd, cam->flags, fourcc); |
1402 | 1414 | ||
1403 | return ret; | 1415 | return ret; |
1404 | } | 1416 | } |
@@ -1410,14 +1422,13 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1410 | struct pxa_camera_dev *pcdev = ici->priv; | 1422 | struct pxa_camera_dev *pcdev = ici->priv; |
1411 | struct device *dev = icd->dev.parent; | 1423 | struct device *dev = icd->dev.parent; |
1412 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1424 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1413 | const struct soc_camera_data_format *cam_fmt = NULL; | ||
1414 | const struct soc_camera_format_xlate *xlate = NULL; | 1425 | const struct soc_camera_format_xlate *xlate = NULL; |
1415 | struct soc_camera_sense sense = { | 1426 | struct soc_camera_sense sense = { |
1416 | .master_clock = pcdev->mclk, | 1427 | .master_clock = pcdev->mclk, |
1417 | .pixel_clock_max = pcdev->ciclk / 4, | 1428 | .pixel_clock_max = pcdev->ciclk / 4, |
1418 | }; | 1429 | }; |
1419 | struct v4l2_pix_format *pix = &f->fmt.pix; | 1430 | struct v4l2_pix_format *pix = &f->fmt.pix; |
1420 | struct v4l2_format cam_f = *f; | 1431 | struct v4l2_mbus_framefmt mf; |
1421 | int ret; | 1432 | int ret; |
1422 | 1433 | ||
1423 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | 1434 | xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); |
@@ -1426,26 +1437,31 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1426 | return -EINVAL; | 1437 | return -EINVAL; |
1427 | } | 1438 | } |
1428 | 1439 | ||
1429 | cam_fmt = xlate->cam_fmt; | ||
1430 | |||
1431 | /* If PCLK is used to latch data from the sensor, check sense */ | 1440 | /* If PCLK is used to latch data from the sensor, check sense */ |
1432 | if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) | 1441 | if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) |
1442 | /* The caller holds a mutex. */ | ||
1433 | icd->sense = &sense; | 1443 | icd->sense = &sense; |
1434 | 1444 | ||
1435 | cam_f.fmt.pix.pixelformat = cam_fmt->fourcc; | 1445 | mf.width = pix->width; |
1436 | ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f); | 1446 | mf.height = pix->height; |
1437 | cam_f.fmt.pix.pixelformat = pix->pixelformat; | 1447 | mf.field = pix->field; |
1438 | *pix = cam_f.fmt.pix; | 1448 | mf.colorspace = pix->colorspace; |
1449 | mf.code = xlate->code; | ||
1450 | |||
1451 | ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); | ||
1452 | |||
1453 | if (mf.code != xlate->code) | ||
1454 | return -EINVAL; | ||
1439 | 1455 | ||
1440 | icd->sense = NULL; | 1456 | icd->sense = NULL; |
1441 | 1457 | ||
1442 | if (ret < 0) { | 1458 | if (ret < 0) { |
1443 | dev_warn(dev, "Failed to configure for format %x\n", | 1459 | dev_warn(dev, "Failed to configure for format %x\n", |
1444 | pix->pixelformat); | 1460 | pix->pixelformat); |
1445 | } else if (pxa_camera_check_frame(pix)) { | 1461 | } else if (pxa_camera_check_frame(mf.width, mf.height)) { |
1446 | dev_warn(dev, | 1462 | dev_warn(dev, |
1447 | "Camera driver produced an unsupported frame %dx%d\n", | 1463 | "Camera driver produced an unsupported frame %dx%d\n", |
1448 | pix->width, pix->height); | 1464 | mf.width, mf.height); |
1449 | ret = -EINVAL; | 1465 | ret = -EINVAL; |
1450 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { | 1466 | } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { |
1451 | if (sense.pixel_clock > sense.pixel_clock_max) { | 1467 | if (sense.pixel_clock > sense.pixel_clock_max) { |
@@ -1457,10 +1473,14 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1457 | recalculate_fifo_timeout(pcdev, sense.pixel_clock); | 1473 | recalculate_fifo_timeout(pcdev, sense.pixel_clock); |
1458 | } | 1474 | } |
1459 | 1475 | ||
1460 | if (!ret) { | 1476 | if (ret < 0) |
1461 | icd->buswidth = xlate->buswidth; | 1477 | return ret; |
1462 | icd->current_fmt = xlate->host_fmt; | 1478 | |
1463 | } | 1479 | pix->width = mf.width; |
1480 | pix->height = mf.height; | ||
1481 | pix->field = mf.field; | ||
1482 | pix->colorspace = mf.colorspace; | ||
1483 | icd->current_fmt = xlate; | ||
1464 | 1484 | ||
1465 | return ret; | 1485 | return ret; |
1466 | } | 1486 | } |
@@ -1468,17 +1488,16 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, | |||
1468 | static int pxa_camera_try_fmt(struct soc_camera_device *icd, | 1488 | static int pxa_camera_try_fmt(struct soc_camera_device *icd, |
1469 | struct v4l2_format *f) | 1489 | struct v4l2_format *f) |
1470 | { | 1490 | { |
1471 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | ||
1472 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1491 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1473 | const struct soc_camera_format_xlate *xlate; | 1492 | const struct soc_camera_format_xlate *xlate; |
1474 | struct v4l2_pix_format *pix = &f->fmt.pix; | 1493 | struct v4l2_pix_format *pix = &f->fmt.pix; |
1494 | struct v4l2_mbus_framefmt mf; | ||
1475 | __u32 pixfmt = pix->pixelformat; | 1495 | __u32 pixfmt = pix->pixelformat; |
1476 | enum v4l2_field field; | ||
1477 | int ret; | 1496 | int ret; |
1478 | 1497 | ||
1479 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 1498 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
1480 | if (!xlate) { | 1499 | if (!xlate) { |
1481 | dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt); | 1500 | dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt); |
1482 | return -EINVAL; | 1501 | return -EINVAL; |
1483 | } | 1502 | } |
1484 | 1503 | ||
@@ -1492,22 +1511,36 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, | |||
1492 | &pix->height, 32, 2048, 0, | 1511 | &pix->height, 32, 2048, 0, |
1493 | pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0); | 1512 | pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0); |
1494 | 1513 | ||
1495 | pix->bytesperline = pix->width * | 1514 | pix->bytesperline = soc_mbus_bytes_per_line(pix->width, |
1496 | DIV_ROUND_UP(xlate->host_fmt->depth, 8); | 1515 | xlate->host_fmt); |
1516 | if (pix->bytesperline < 0) | ||
1517 | return pix->bytesperline; | ||
1497 | pix->sizeimage = pix->height * pix->bytesperline; | 1518 | pix->sizeimage = pix->height * pix->bytesperline; |
1498 | 1519 | ||
1499 | /* camera has to see its format, but the user the original one */ | ||
1500 | pix->pixelformat = xlate->cam_fmt->fourcc; | ||
1501 | /* limit to sensor capabilities */ | 1520 | /* limit to sensor capabilities */ |
1502 | ret = v4l2_subdev_call(sd, video, try_fmt, f); | 1521 | mf.width = pix->width; |
1503 | pix->pixelformat = pixfmt; | 1522 | mf.height = pix->height; |
1523 | mf.field = pix->field; | ||
1524 | mf.colorspace = pix->colorspace; | ||
1525 | mf.code = xlate->code; | ||
1504 | 1526 | ||
1505 | field = pix->field; | 1527 | ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); |
1528 | if (ret < 0) | ||
1529 | return ret; | ||
1506 | 1530 | ||
1507 | if (field == V4L2_FIELD_ANY) { | 1531 | pix->width = mf.width; |
1508 | pix->field = V4L2_FIELD_NONE; | 1532 | pix->height = mf.height; |
1509 | } else if (field != V4L2_FIELD_NONE) { | 1533 | pix->colorspace = mf.colorspace; |
1510 | dev_err(icd->dev.parent, "Field type %d unsupported.\n", field); | 1534 | |
1535 | switch (mf.field) { | ||
1536 | case V4L2_FIELD_ANY: | ||
1537 | case V4L2_FIELD_NONE: | ||
1538 | pix->field = V4L2_FIELD_NONE; | ||
1539 | break; | ||
1540 | default: | ||
1541 | /* TODO: support interlaced at least in pass-through mode */ | ||
1542 | dev_err(icd->dev.parent, "Field type %d unsupported.\n", | ||
1543 | mf.field); | ||
1511 | return -EINVAL; | 1544 | return -EINVAL; |
1512 | } | 1545 | } |
1513 | 1546 | ||
@@ -1519,10 +1552,12 @@ static int pxa_camera_reqbufs(struct soc_camera_file *icf, | |||
1519 | { | 1552 | { |
1520 | int i; | 1553 | int i; |
1521 | 1554 | ||
1522 | /* This is for locking debugging only. I removed spinlocks and now I | 1555 | /* |
1556 | * This is for locking debugging only. I removed spinlocks and now I | ||
1523 | * check whether .prepare is ever called on a linked buffer, or whether | 1557 | * check whether .prepare is ever called on a linked buffer, or whether |
1524 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now | 1558 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now |
1525 | * it hadn't triggered */ | 1559 | * it hadn't triggered |
1560 | */ | ||
1526 | for (i = 0; i < p->count; i++) { | 1561 | for (i = 0; i < p->count; i++) { |
1527 | struct pxa_buffer *buf = container_of(icf->vb_vidq.bufs[i], | 1562 | struct pxa_buffer *buf = container_of(icf->vb_vidq.bufs[i], |
1528 | struct pxa_buffer, vb); | 1563 | struct pxa_buffer, vb); |
@@ -1657,8 +1692,10 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev) | |||
1657 | pcdev->platform_flags = pcdev->pdata->flags; | 1692 | pcdev->platform_flags = pcdev->pdata->flags; |
1658 | if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 | | 1693 | if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 | |
1659 | PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) { | 1694 | PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) { |
1660 | /* Platform hasn't set available data widths. This is bad. | 1695 | /* |
1661 | * Warn and use a default. */ | 1696 | * Platform hasn't set available data widths. This is bad. |
1697 | * Warn and use a default. | ||
1698 | */ | ||
1662 | dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " | 1699 | dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " |
1663 | "data widths, using default 10 bit\n"); | 1700 | "data widths, using default 10 bit\n"); |
1664 | pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; | 1701 | pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; |
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c index 373f2a30a67..7e42989ce0e 100644 --- a/drivers/media/video/rj54n1cb0c.c +++ b/drivers/media/video/rj54n1cb0c.c | |||
@@ -13,9 +13,11 @@ | |||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/videodev2.h> | 14 | #include <linux/videodev2.h> |
15 | 15 | ||
16 | #include <media/rj54n1cb0c.h> | ||
17 | #include <media/soc_camera.h> | ||
18 | #include <media/soc_mediabus.h> | ||
16 | #include <media/v4l2-subdev.h> | 19 | #include <media/v4l2-subdev.h> |
17 | #include <media/v4l2-chip-ident.h> | 20 | #include <media/v4l2-chip-ident.h> |
18 | #include <media/soc_camera.h> | ||
19 | 21 | ||
20 | #define RJ54N1_DEV_CODE 0x0400 | 22 | #define RJ54N1_DEV_CODE 0x0400 |
21 | #define RJ54N1_DEV_CODE2 0x0401 | 23 | #define RJ54N1_DEV_CODE2 0x0401 |
@@ -38,6 +40,7 @@ | |||
38 | #define RJ54N1_H_OBEN_OFS 0x0413 | 40 | #define RJ54N1_H_OBEN_OFS 0x0413 |
39 | #define RJ54N1_V_OBEN_OFS 0x0414 | 41 | #define RJ54N1_V_OBEN_OFS 0x0414 |
40 | #define RJ54N1_RESIZE_CONTROL 0x0415 | 42 | #define RJ54N1_RESIZE_CONTROL 0x0415 |
43 | #define RJ54N1_STILL_CONTROL 0x0417 | ||
41 | #define RJ54N1_INC_USE_SEL_H 0x0425 | 44 | #define RJ54N1_INC_USE_SEL_H 0x0425 |
42 | #define RJ54N1_INC_USE_SEL_L 0x0426 | 45 | #define RJ54N1_INC_USE_SEL_L 0x0426 |
43 | #define RJ54N1_MIRROR_STILL_MODE 0x0427 | 46 | #define RJ54N1_MIRROR_STILL_MODE 0x0427 |
@@ -49,10 +52,21 @@ | |||
49 | #define RJ54N1_RA_SEL_UL 0x0530 | 52 | #define RJ54N1_RA_SEL_UL 0x0530 |
50 | #define RJ54N1_BYTE_SWAP 0x0531 | 53 | #define RJ54N1_BYTE_SWAP 0x0531 |
51 | #define RJ54N1_OUT_SIGPO 0x053b | 54 | #define RJ54N1_OUT_SIGPO 0x053b |
55 | #define RJ54N1_WB_SEL_WEIGHT_I 0x054e | ||
56 | #define RJ54N1_BIT8_WB 0x0569 | ||
57 | #define RJ54N1_HCAPS_WB 0x056a | ||
58 | #define RJ54N1_VCAPS_WB 0x056b | ||
59 | #define RJ54N1_HCAPE_WB 0x056c | ||
60 | #define RJ54N1_VCAPE_WB 0x056d | ||
61 | #define RJ54N1_EXPOSURE_CONTROL 0x058c | ||
52 | #define RJ54N1_FRAME_LENGTH_S_H 0x0595 | 62 | #define RJ54N1_FRAME_LENGTH_S_H 0x0595 |
53 | #define RJ54N1_FRAME_LENGTH_S_L 0x0596 | 63 | #define RJ54N1_FRAME_LENGTH_S_L 0x0596 |
54 | #define RJ54N1_FRAME_LENGTH_P_H 0x0597 | 64 | #define RJ54N1_FRAME_LENGTH_P_H 0x0597 |
55 | #define RJ54N1_FRAME_LENGTH_P_L 0x0598 | 65 | #define RJ54N1_FRAME_LENGTH_P_L 0x0598 |
66 | #define RJ54N1_PEAK_H 0x05b7 | ||
67 | #define RJ54N1_PEAK_50 0x05b8 | ||
68 | #define RJ54N1_PEAK_60 0x05b9 | ||
69 | #define RJ54N1_PEAK_DIFF 0x05ba | ||
56 | #define RJ54N1_IOC 0x05ef | 70 | #define RJ54N1_IOC 0x05ef |
57 | #define RJ54N1_TG_BYPASS 0x0700 | 71 | #define RJ54N1_TG_BYPASS 0x0700 |
58 | #define RJ54N1_PLL_L 0x0701 | 72 | #define RJ54N1_PLL_L 0x0701 |
@@ -68,6 +82,7 @@ | |||
68 | #define RJ54N1_OCLK_SEL_EN 0x0713 | 82 | #define RJ54N1_OCLK_SEL_EN 0x0713 |
69 | #define RJ54N1_CLK_RST 0x0717 | 83 | #define RJ54N1_CLK_RST 0x0717 |
70 | #define RJ54N1_RESET_STANDBY 0x0718 | 84 | #define RJ54N1_RESET_STANDBY 0x0718 |
85 | #define RJ54N1_FWFLG 0x07fe | ||
71 | 86 | ||
72 | #define E_EXCLK (1 << 7) | 87 | #define E_EXCLK (1 << 7) |
73 | #define SOFT_STDBY (1 << 4) | 88 | #define SOFT_STDBY (1 << 4) |
@@ -78,29 +93,53 @@ | |||
78 | #define RESIZE_HOLD_SEL (1 << 2) | 93 | #define RESIZE_HOLD_SEL (1 << 2) |
79 | #define RESIZE_GO (1 << 1) | 94 | #define RESIZE_GO (1 << 1) |
80 | 95 | ||
96 | /* | ||
97 | * When cropping, the camera automatically centers the cropped region, there | ||
98 | * doesn't seem to be a way to specify an explicit location of the rectangle. | ||
99 | */ | ||
81 | #define RJ54N1_COLUMN_SKIP 0 | 100 | #define RJ54N1_COLUMN_SKIP 0 |
82 | #define RJ54N1_ROW_SKIP 0 | 101 | #define RJ54N1_ROW_SKIP 0 |
83 | #define RJ54N1_MAX_WIDTH 1600 | 102 | #define RJ54N1_MAX_WIDTH 1600 |
84 | #define RJ54N1_MAX_HEIGHT 1200 | 103 | #define RJ54N1_MAX_HEIGHT 1200 |
85 | 104 | ||
105 | #define PLL_L 2 | ||
106 | #define PLL_N 0x31 | ||
107 | |||
86 | /* I2C addresses: 0x50, 0x51, 0x60, 0x61 */ | 108 | /* I2C addresses: 0x50, 0x51, 0x60, 0x61 */ |
87 | 109 | ||
88 | static const struct soc_camera_data_format rj54n1_colour_formats[] = { | 110 | /* RJ54N1CB0C has only one fixed colorspace per pixelcode */ |
89 | { | 111 | struct rj54n1_datafmt { |
90 | .name = "YUYV", | 112 | enum v4l2_mbus_pixelcode code; |
91 | .depth = 16, | 113 | enum v4l2_colorspace colorspace; |
92 | .fourcc = V4L2_PIX_FMT_YUYV, | 114 | }; |
93 | .colorspace = V4L2_COLORSPACE_JPEG, | 115 | |
94 | }, { | 116 | /* Find a data format by a pixel code in an array */ |
95 | .name = "RGB565", | 117 | static const struct rj54n1_datafmt *rj54n1_find_datafmt( |
96 | .depth = 16, | 118 | enum v4l2_mbus_pixelcode code, const struct rj54n1_datafmt *fmt, |
97 | .fourcc = V4L2_PIX_FMT_RGB565, | 119 | int n) |
98 | .colorspace = V4L2_COLORSPACE_SRGB, | 120 | { |
99 | } | 121 | int i; |
122 | for (i = 0; i < n; i++) | ||
123 | if (fmt[i].code == code) | ||
124 | return fmt + i; | ||
125 | |||
126 | return NULL; | ||
127 | } | ||
128 | |||
129 | static const struct rj54n1_datafmt rj54n1_colour_fmts[] = { | ||
130 | {V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG}, | ||
131 | {V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG}, | ||
132 | {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, | ||
133 | {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, | ||
134 | {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, | ||
135 | {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB}, | ||
136 | {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, | ||
137 | {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB}, | ||
138 | {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, | ||
100 | }; | 139 | }; |
101 | 140 | ||
102 | struct rj54n1_clock_div { | 141 | struct rj54n1_clock_div { |
103 | u8 ratio_tg; | 142 | u8 ratio_tg; /* can be 0 or an odd number */ |
104 | u8 ratio_t; | 143 | u8 ratio_t; |
105 | u8 ratio_r; | 144 | u8 ratio_r; |
106 | u8 ratio_op; | 145 | u8 ratio_op; |
@@ -109,12 +148,14 @@ struct rj54n1_clock_div { | |||
109 | 148 | ||
110 | struct rj54n1 { | 149 | struct rj54n1 { |
111 | struct v4l2_subdev subdev; | 150 | struct v4l2_subdev subdev; |
151 | struct rj54n1_clock_div clk_div; | ||
152 | const struct rj54n1_datafmt *fmt; | ||
112 | struct v4l2_rect rect; /* Sensor window */ | 153 | struct v4l2_rect rect; /* Sensor window */ |
154 | unsigned int tgclk_mhz; | ||
155 | bool auto_wb; | ||
113 | unsigned short width; /* Output window */ | 156 | unsigned short width; /* Output window */ |
114 | unsigned short height; | 157 | unsigned short height; |
115 | unsigned short resize; /* Sensor * 1024 / resize = Output */ | 158 | unsigned short resize; /* Sensor * 1024 / resize = Output */ |
116 | struct rj54n1_clock_div clk_div; | ||
117 | u32 fourcc; | ||
118 | unsigned short scale; | 159 | unsigned short scale; |
119 | u8 bank; | 160 | u8 bank; |
120 | }; | 161 | }; |
@@ -171,7 +212,7 @@ const static struct rj54n1_reg_val bank_7[] = { | |||
171 | {0x714, 0xff}, | 212 | {0x714, 0xff}, |
172 | {0x715, 0xff}, | 213 | {0x715, 0xff}, |
173 | {0x716, 0x1f}, | 214 | {0x716, 0x1f}, |
174 | {0x7FE, 0x02}, | 215 | {0x7FE, 2}, |
175 | }; | 216 | }; |
176 | 217 | ||
177 | const static struct rj54n1_reg_val bank_8[] = { | 218 | const static struct rj54n1_reg_val bank_8[] = { |
@@ -359,7 +400,7 @@ const static struct rj54n1_reg_val bank_8[] = { | |||
359 | {0x8BB, 0x00}, | 400 | {0x8BB, 0x00}, |
360 | {0x8BC, 0xFF}, | 401 | {0x8BC, 0xFF}, |
361 | {0x8BD, 0x00}, | 402 | {0x8BD, 0x00}, |
362 | {0x8FE, 0x02}, | 403 | {0x8FE, 2}, |
363 | }; | 404 | }; |
364 | 405 | ||
365 | const static struct rj54n1_reg_val bank_10[] = { | 406 | const static struct rj54n1_reg_val bank_10[] = { |
@@ -440,12 +481,24 @@ static int reg_write_multiple(struct i2c_client *client, | |||
440 | return 0; | 481 | return 0; |
441 | } | 482 | } |
442 | 483 | ||
443 | static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable) | 484 | static int rj54n1_enum_fmt(struct v4l2_subdev *sd, int index, |
485 | enum v4l2_mbus_pixelcode *code) | ||
444 | { | 486 | { |
445 | /* TODO: start / stop streaming */ | 487 | if ((unsigned int)index >= ARRAY_SIZE(rj54n1_colour_fmts)) |
488 | return -EINVAL; | ||
489 | |||
490 | *code = rj54n1_colour_fmts[index].code; | ||
446 | return 0; | 491 | return 0; |
447 | } | 492 | } |
448 | 493 | ||
494 | static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable) | ||
495 | { | ||
496 | struct i2c_client *client = sd->priv; | ||
497 | |||
498 | /* Switch between preview and still shot modes */ | ||
499 | return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80); | ||
500 | } | ||
501 | |||
449 | static int rj54n1_set_bus_param(struct soc_camera_device *icd, | 502 | static int rj54n1_set_bus_param(struct soc_camera_device *icd, |
450 | unsigned long flags) | 503 | unsigned long flags) |
451 | { | 504 | { |
@@ -502,6 +555,44 @@ static int rj54n1_commit(struct i2c_client *client) | |||
502 | return ret; | 555 | return ret; |
503 | } | 556 | } |
504 | 557 | ||
558 | static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, | ||
559 | u32 *out_w, u32 *out_h); | ||
560 | |||
561 | static int rj54n1_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | ||
562 | { | ||
563 | struct i2c_client *client = sd->priv; | ||
564 | struct rj54n1 *rj54n1 = to_rj54n1(client); | ||
565 | struct v4l2_rect *rect = &a->c; | ||
566 | unsigned int dummy, output_w, output_h, | ||
567 | input_w = rect->width, input_h = rect->height; | ||
568 | int ret; | ||
569 | |||
570 | /* arbitrary minimum width and height, edges unimportant */ | ||
571 | soc_camera_limit_side(&dummy, &input_w, | ||
572 | RJ54N1_COLUMN_SKIP, 8, RJ54N1_MAX_WIDTH); | ||
573 | |||
574 | soc_camera_limit_side(&dummy, &input_h, | ||
575 | RJ54N1_ROW_SKIP, 8, RJ54N1_MAX_HEIGHT); | ||
576 | |||
577 | output_w = (input_w * 1024 + rj54n1->resize / 2) / rj54n1->resize; | ||
578 | output_h = (input_h * 1024 + rj54n1->resize / 2) / rj54n1->resize; | ||
579 | |||
580 | dev_dbg(&client->dev, "Scaling for %ux%u : %u = %ux%u\n", | ||
581 | input_w, input_h, rj54n1->resize, output_w, output_h); | ||
582 | |||
583 | ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h); | ||
584 | if (ret < 0) | ||
585 | return ret; | ||
586 | |||
587 | rj54n1->width = output_w; | ||
588 | rj54n1->height = output_h; | ||
589 | rj54n1->resize = ret; | ||
590 | rj54n1->rect.width = input_w; | ||
591 | rj54n1->rect.height = input_h; | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
505 | static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 596 | static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
506 | { | 597 | { |
507 | struct i2c_client *client = sd->priv; | 598 | struct i2c_client *client = sd->priv; |
@@ -527,16 +618,17 @@ static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
527 | return 0; | 618 | return 0; |
528 | } | 619 | } |
529 | 620 | ||
530 | static int rj54n1_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 621 | static int rj54n1_g_fmt(struct v4l2_subdev *sd, |
622 | struct v4l2_mbus_framefmt *mf) | ||
531 | { | 623 | { |
532 | struct i2c_client *client = sd->priv; | 624 | struct i2c_client *client = sd->priv; |
533 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 625 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
534 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
535 | 626 | ||
536 | pix->pixelformat = rj54n1->fourcc; | 627 | mf->code = rj54n1->fmt->code; |
537 | pix->field = V4L2_FIELD_NONE; | 628 | mf->colorspace = rj54n1->fmt->colorspace; |
538 | pix->width = rj54n1->width; | 629 | mf->field = V4L2_FIELD_NONE; |
539 | pix->height = rj54n1->height; | 630 | mf->width = rj54n1->width; |
631 | mf->height = rj54n1->height; | ||
540 | 632 | ||
541 | return 0; | 633 | return 0; |
542 | } | 634 | } |
@@ -550,11 +642,44 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, | |||
550 | u32 *out_w, u32 *out_h) | 642 | u32 *out_w, u32 *out_h) |
551 | { | 643 | { |
552 | struct i2c_client *client = sd->priv; | 644 | struct i2c_client *client = sd->priv; |
645 | struct rj54n1 *rj54n1 = to_rj54n1(client); | ||
553 | unsigned int skip, resize, input_w = *in_w, input_h = *in_h, | 646 | unsigned int skip, resize, input_w = *in_w, input_h = *in_h, |
554 | output_w = *out_w, output_h = *out_h; | 647 | output_w = *out_w, output_h = *out_h; |
555 | u16 inc_sel; | 648 | u16 inc_sel, wb_bit8, wb_left, wb_right, wb_top, wb_bottom; |
649 | unsigned int peak, peak_50, peak_60; | ||
556 | int ret; | 650 | int ret; |
557 | 651 | ||
652 | /* | ||
653 | * We have a problem with crops, where the window is larger than 512x384 | ||
654 | * and output window is larger than a half of the input one. In this | ||
655 | * case we have to either reduce the input window to equal or below | ||
656 | * 512x384 or the output window to equal or below 1/2 of the input. | ||
657 | */ | ||
658 | if (output_w > max(512U, input_w / 2)) { | ||
659 | if (2 * output_w > RJ54N1_MAX_WIDTH) { | ||
660 | input_w = RJ54N1_MAX_WIDTH; | ||
661 | output_w = RJ54N1_MAX_WIDTH / 2; | ||
662 | } else { | ||
663 | input_w = output_w * 2; | ||
664 | } | ||
665 | |||
666 | dev_dbg(&client->dev, "Adjusted output width: in %u, out %u\n", | ||
667 | input_w, output_w); | ||
668 | } | ||
669 | |||
670 | if (output_h > max(384U, input_h / 2)) { | ||
671 | if (2 * output_h > RJ54N1_MAX_HEIGHT) { | ||
672 | input_h = RJ54N1_MAX_HEIGHT; | ||
673 | output_h = RJ54N1_MAX_HEIGHT / 2; | ||
674 | } else { | ||
675 | input_h = output_h * 2; | ||
676 | } | ||
677 | |||
678 | dev_dbg(&client->dev, "Adjusted output height: in %u, out %u\n", | ||
679 | input_h, output_h); | ||
680 | } | ||
681 | |||
682 | /* Idea: use the read mode for snapshots, handle separate geometries */ | ||
558 | ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L, | 683 | ret = rj54n1_set_rect(client, RJ54N1_X_OUTPUT_SIZE_S_L, |
559 | RJ54N1_Y_OUTPUT_SIZE_S_L, | 684 | RJ54N1_Y_OUTPUT_SIZE_S_L, |
560 | RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h); | 685 | RJ54N1_XY_OUTPUT_SIZE_S_H, output_w, output_h); |
@@ -566,17 +691,27 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, | |||
566 | if (ret < 0) | 691 | if (ret < 0) |
567 | return ret; | 692 | return ret; |
568 | 693 | ||
569 | if (output_w > input_w || output_h > input_h) { | 694 | if (output_w > input_w && output_h > input_h) { |
570 | input_w = output_w; | 695 | input_w = output_w; |
571 | input_h = output_h; | 696 | input_h = output_h; |
572 | 697 | ||
573 | resize = 1024; | 698 | resize = 1024; |
574 | } else { | 699 | } else { |
575 | unsigned int resize_x, resize_y; | 700 | unsigned int resize_x, resize_y; |
576 | resize_x = input_w * 1024 / output_w; | 701 | resize_x = (input_w * 1024 + output_w / 2) / output_w; |
577 | resize_y = input_h * 1024 / output_h; | 702 | resize_y = (input_h * 1024 + output_h / 2) / output_h; |
578 | 703 | ||
579 | resize = min(resize_x, resize_y); | 704 | /* We want max(resize_x, resize_y), check if it still fits */ |
705 | if (resize_x > resize_y && | ||
706 | (output_h * resize_x + 512) / 1024 > RJ54N1_MAX_HEIGHT) | ||
707 | resize = (RJ54N1_MAX_HEIGHT * 1024 + output_h / 2) / | ||
708 | output_h; | ||
709 | else if (resize_y > resize_x && | ||
710 | (output_w * resize_y + 512) / 1024 > RJ54N1_MAX_WIDTH) | ||
711 | resize = (RJ54N1_MAX_WIDTH * 1024 + output_w / 2) / | ||
712 | output_w; | ||
713 | else | ||
714 | resize = max(resize_x, resize_y); | ||
580 | 715 | ||
581 | /* Prohibited value ranges */ | 716 | /* Prohibited value ranges */ |
582 | switch (resize) { | 717 | switch (resize) { |
@@ -589,12 +724,9 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, | |||
589 | case 8160 ... 8191: | 724 | case 8160 ... 8191: |
590 | resize = 8159; | 725 | resize = 8159; |
591 | break; | 726 | break; |
592 | case 16320 ... 16383: | 727 | case 16320 ... 16384: |
593 | resize = 16319; | 728 | resize = 16319; |
594 | } | 729 | } |
595 | |||
596 | input_w = output_w * resize / 1024; | ||
597 | input_h = output_h * resize / 1024; | ||
598 | } | 730 | } |
599 | 731 | ||
600 | /* Set scaling */ | 732 | /* Set scaling */ |
@@ -607,9 +739,18 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, | |||
607 | 739 | ||
608 | /* | 740 | /* |
609 | * Configure a skipping bitmask. The sensor will select a skipping value | 741 | * Configure a skipping bitmask. The sensor will select a skipping value |
610 | * among set bits automatically. | 742 | * among set bits automatically. This is very unclear in the datasheet |
743 | * too. I was told, in this register one enables all skipping values, | ||
744 | * that are required for a specific resize, and the camera selects | ||
745 | * automatically, which ones to use. But it is unclear how to identify, | ||
746 | * which cropping values are needed. Secondly, why don't we just set all | ||
747 | * bits and let the camera choose? Would it increase processing time and | ||
748 | * reduce the framerate? Using 0xfffc for INC_USE_SEL doesn't seem to | ||
749 | * improve the image quality or stability for larger frames (see comment | ||
750 | * above), but I didn't check the framerate. | ||
611 | */ | 751 | */ |
612 | skip = min(resize / 1024, (unsigned)15); | 752 | skip = min(resize / 1024, (unsigned)15); |
753 | |||
613 | inc_sel = 1 << skip; | 754 | inc_sel = 1 << skip; |
614 | 755 | ||
615 | if (inc_sel <= 2) | 756 | if (inc_sel <= 2) |
@@ -621,6 +762,43 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, | |||
621 | if (!ret) | 762 | if (!ret) |
622 | ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8); | 763 | ret = reg_write(client, RJ54N1_INC_USE_SEL_H, inc_sel >> 8); |
623 | 764 | ||
765 | if (!rj54n1->auto_wb) { | ||
766 | /* Auto white balance window */ | ||
767 | wb_left = output_w / 16; | ||
768 | wb_right = (3 * output_w / 4 - 3) / 4; | ||
769 | wb_top = output_h / 16; | ||
770 | wb_bottom = (3 * output_h / 4 - 3) / 4; | ||
771 | wb_bit8 = ((wb_left >> 2) & 0x40) | ((wb_top >> 4) & 0x10) | | ||
772 | ((wb_right >> 6) & 4) | ((wb_bottom >> 8) & 1); | ||
773 | |||
774 | if (!ret) | ||
775 | ret = reg_write(client, RJ54N1_BIT8_WB, wb_bit8); | ||
776 | if (!ret) | ||
777 | ret = reg_write(client, RJ54N1_HCAPS_WB, wb_left); | ||
778 | if (!ret) | ||
779 | ret = reg_write(client, RJ54N1_VCAPS_WB, wb_top); | ||
780 | if (!ret) | ||
781 | ret = reg_write(client, RJ54N1_HCAPE_WB, wb_right); | ||
782 | if (!ret) | ||
783 | ret = reg_write(client, RJ54N1_VCAPE_WB, wb_bottom); | ||
784 | } | ||
785 | |||
786 | /* Antiflicker */ | ||
787 | peak = 12 * RJ54N1_MAX_WIDTH * (1 << 14) * resize / rj54n1->tgclk_mhz / | ||
788 | 10000; | ||
789 | peak_50 = peak / 6; | ||
790 | peak_60 = peak / 5; | ||
791 | |||
792 | if (!ret) | ||
793 | ret = reg_write(client, RJ54N1_PEAK_H, | ||
794 | ((peak_50 >> 4) & 0xf0) | (peak_60 >> 8)); | ||
795 | if (!ret) | ||
796 | ret = reg_write(client, RJ54N1_PEAK_50, peak_50); | ||
797 | if (!ret) | ||
798 | ret = reg_write(client, RJ54N1_PEAK_60, peak_60); | ||
799 | if (!ret) | ||
800 | ret = reg_write(client, RJ54N1_PEAK_DIFF, peak / 150); | ||
801 | |||
624 | /* Start resizing */ | 802 | /* Start resizing */ |
625 | if (!ret) | 803 | if (!ret) |
626 | ret = reg_write(client, RJ54N1_RESIZE_CONTROL, | 804 | ret = reg_write(client, RJ54N1_RESIZE_CONTROL, |
@@ -629,8 +807,6 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, | |||
629 | if (ret < 0) | 807 | if (ret < 0) |
630 | return ret; | 808 | return ret; |
631 | 809 | ||
632 | dev_dbg(&client->dev, "resize %u, skip %u\n", resize, skip); | ||
633 | |||
634 | /* Constant taken from manufacturer's example */ | 810 | /* Constant taken from manufacturer's example */ |
635 | msleep(230); | 811 | msleep(230); |
636 | 812 | ||
@@ -638,11 +814,14 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, u32 *in_w, u32 *in_h, | |||
638 | if (ret < 0) | 814 | if (ret < 0) |
639 | return ret; | 815 | return ret; |
640 | 816 | ||
641 | *in_w = input_w; | 817 | *in_w = (output_w * resize + 512) / 1024; |
642 | *in_h = input_h; | 818 | *in_h = (output_h * resize + 512) / 1024; |
643 | *out_w = output_w; | 819 | *out_w = output_w; |
644 | *out_h = output_h; | 820 | *out_h = output_h; |
645 | 821 | ||
822 | dev_dbg(&client->dev, "Scaled for %ux%u : %u = %ux%u, skip %u\n", | ||
823 | *in_w, *in_h, resize, output_w, output_h, skip); | ||
824 | |||
646 | return resize; | 825 | return resize; |
647 | } | 826 | } |
648 | 827 | ||
@@ -653,14 +832,14 @@ static int rj54n1_set_clock(struct i2c_client *client) | |||
653 | 832 | ||
654 | /* Enable external clock */ | 833 | /* Enable external clock */ |
655 | ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY); | 834 | ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK | SOFT_STDBY); |
656 | /* Leave stand-by */ | 835 | /* Leave stand-by. Note: use this when implementing suspend / resume */ |
657 | if (!ret) | 836 | if (!ret) |
658 | ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK); | 837 | ret = reg_write(client, RJ54N1_RESET_STANDBY, E_EXCLK); |
659 | 838 | ||
660 | if (!ret) | 839 | if (!ret) |
661 | ret = reg_write(client, RJ54N1_PLL_L, 2); | 840 | ret = reg_write(client, RJ54N1_PLL_L, PLL_L); |
662 | if (!ret) | 841 | if (!ret) |
663 | ret = reg_write(client, RJ54N1_PLL_N, 0x31); | 842 | ret = reg_write(client, RJ54N1_PLL_N, PLL_N); |
664 | 843 | ||
665 | /* TGCLK dividers */ | 844 | /* TGCLK dividers */ |
666 | if (!ret) | 845 | if (!ret) |
@@ -719,6 +898,7 @@ static int rj54n1_set_clock(struct i2c_client *client) | |||
719 | "Resetting RJ54N1CB0C clock failed: %d!\n", ret); | 898 | "Resetting RJ54N1CB0C clock failed: %d!\n", ret); |
720 | return -EIO; | 899 | return -EIO; |
721 | } | 900 | } |
901 | |||
722 | /* Start the PLL */ | 902 | /* Start the PLL */ |
723 | ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1); | 903 | ret = reg_set(client, RJ54N1_OCLK_DSP, 1, 1); |
724 | 904 | ||
@@ -731,6 +911,7 @@ static int rj54n1_set_clock(struct i2c_client *client) | |||
731 | 911 | ||
732 | static int rj54n1_reg_init(struct i2c_client *client) | 912 | static int rj54n1_reg_init(struct i2c_client *client) |
733 | { | 913 | { |
914 | struct rj54n1 *rj54n1 = to_rj54n1(client); | ||
734 | int ret = rj54n1_set_clock(client); | 915 | int ret = rj54n1_set_clock(client); |
735 | 916 | ||
736 | if (!ret) | 917 | if (!ret) |
@@ -753,14 +934,26 @@ static int rj54n1_reg_init(struct i2c_client *client) | |||
753 | if (!ret) | 934 | if (!ret) |
754 | ret = reg_write(client, RJ54N1_Y_GAIN, 0x84); | 935 | ret = reg_write(client, RJ54N1_Y_GAIN, 0x84); |
755 | 936 | ||
756 | /* Mirror the image back: default is upside down and left-to-right... */ | 937 | /* |
938 | * Mirror the image back: default is upside down and left-to-right... | ||
939 | * Set manual preview / still shot switching | ||
940 | */ | ||
757 | if (!ret) | 941 | if (!ret) |
758 | ret = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 3, 3); | 942 | ret = reg_write(client, RJ54N1_MIRROR_STILL_MODE, 0x27); |
759 | 943 | ||
760 | if (!ret) | 944 | if (!ret) |
761 | ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4)); | 945 | ret = reg_write_multiple(client, bank_4, ARRAY_SIZE(bank_4)); |
946 | |||
947 | /* Auto exposure area */ | ||
762 | if (!ret) | 948 | if (!ret) |
949 | ret = reg_write(client, RJ54N1_EXPOSURE_CONTROL, 0x80); | ||
950 | /* Check current auto WB config */ | ||
951 | if (!ret) | ||
952 | ret = reg_read(client, RJ54N1_WB_SEL_WEIGHT_I); | ||
953 | if (ret >= 0) { | ||
954 | rj54n1->auto_wb = ret & 0x80; | ||
763 | ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5)); | 955 | ret = reg_write_multiple(client, bank_5, ARRAY_SIZE(bank_5)); |
956 | } | ||
764 | if (!ret) | 957 | if (!ret) |
765 | ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8)); | 958 | ret = reg_write_multiple(client, bank_8, ARRAY_SIZE(bank_8)); |
766 | 959 | ||
@@ -777,8 +970,9 @@ static int rj54n1_reg_init(struct i2c_client *client) | |||
777 | ret = reg_write(client, RJ54N1_RESET_STANDBY, | 970 | ret = reg_write(client, RJ54N1_RESET_STANDBY, |
778 | E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX); | 971 | E_EXCLK | DSP_RSTX | TG_RSTX | SEN_RSTX); |
779 | 972 | ||
973 | /* Start register update? Same register as 0x?FE in many bank_* sets */ | ||
780 | if (!ret) | 974 | if (!ret) |
781 | ret = reg_write(client, 0x7fe, 2); | 975 | ret = reg_write(client, RJ54N1_FWFLG, 2); |
782 | 976 | ||
783 | /* Constant taken from manufacturer's example */ | 977 | /* Constant taken from manufacturer's example */ |
784 | msleep(700); | 978 | msleep(700); |
@@ -786,27 +980,44 @@ static int rj54n1_reg_init(struct i2c_client *client) | |||
786 | return ret; | 980 | return ret; |
787 | } | 981 | } |
788 | 982 | ||
789 | /* FIXME: streaming output only up to 800x600 is functional */ | 983 | static int rj54n1_try_fmt(struct v4l2_subdev *sd, |
790 | static int rj54n1_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 984 | struct v4l2_mbus_framefmt *mf) |
791 | { | 985 | { |
792 | struct v4l2_pix_format *pix = &f->fmt.pix; | 986 | struct i2c_client *client = sd->priv; |
987 | struct rj54n1 *rj54n1 = to_rj54n1(client); | ||
988 | const struct rj54n1_datafmt *fmt; | ||
989 | int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 || | ||
990 | mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE || | ||
991 | mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE || | ||
992 | mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE || | ||
993 | mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE; | ||
994 | |||
995 | dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n", | ||
996 | __func__, mf->code, mf->width, mf->height); | ||
997 | |||
998 | fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts, | ||
999 | ARRAY_SIZE(rj54n1_colour_fmts)); | ||
1000 | if (!fmt) { | ||
1001 | fmt = rj54n1->fmt; | ||
1002 | mf->code = fmt->code; | ||
1003 | } | ||
793 | 1004 | ||
794 | pix->field = V4L2_FIELD_NONE; | 1005 | mf->field = V4L2_FIELD_NONE; |
1006 | mf->colorspace = fmt->colorspace; | ||
795 | 1007 | ||
796 | if (pix->width > 800) | 1008 | v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align, |
797 | pix->width = 800; | 1009 | &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0); |
798 | if (pix->height > 600) | ||
799 | pix->height = 600; | ||
800 | 1010 | ||
801 | return 0; | 1011 | return 0; |
802 | } | 1012 | } |
803 | 1013 | ||
804 | static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 1014 | static int rj54n1_s_fmt(struct v4l2_subdev *sd, |
1015 | struct v4l2_mbus_framefmt *mf) | ||
805 | { | 1016 | { |
806 | struct i2c_client *client = sd->priv; | 1017 | struct i2c_client *client = sd->priv; |
807 | struct rj54n1 *rj54n1 = to_rj54n1(client); | 1018 | struct rj54n1 *rj54n1 = to_rj54n1(client); |
808 | struct v4l2_pix_format *pix = &f->fmt.pix; | 1019 | const struct rj54n1_datafmt *fmt; |
809 | unsigned int output_w, output_h, | 1020 | unsigned int output_w, output_h, max_w, max_h, |
810 | input_w = rj54n1->rect.width, input_h = rj54n1->rect.height; | 1021 | input_w = rj54n1->rect.width, input_h = rj54n1->rect.height; |
811 | int ret; | 1022 | int ret; |
812 | 1023 | ||
@@ -814,14 +1025,13 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |||
814 | * The host driver can call us without .try_fmt(), so, we have to take | 1025 | * The host driver can call us without .try_fmt(), so, we have to take |
815 | * care ourseleves | 1026 | * care ourseleves |
816 | */ | 1027 | */ |
817 | ret = rj54n1_try_fmt(sd, f); | 1028 | rj54n1_try_fmt(sd, mf); |
818 | 1029 | ||
819 | /* | 1030 | /* |
820 | * Verify if the sensor has just been powered on. TODO: replace this | 1031 | * Verify if the sensor has just been powered on. TODO: replace this |
821 | * with proper PM, when a suitable API is available. | 1032 | * with proper PM, when a suitable API is available. |
822 | */ | 1033 | */ |
823 | if (!ret) | 1034 | ret = reg_read(client, RJ54N1_RESET_STANDBY); |
824 | ret = reg_read(client, RJ54N1_RESET_STANDBY); | ||
825 | if (ret < 0) | 1035 | if (ret < 0) |
826 | return ret; | 1036 | return ret; |
827 | 1037 | ||
@@ -831,50 +1041,105 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |||
831 | return ret; | 1041 | return ret; |
832 | } | 1042 | } |
833 | 1043 | ||
1044 | dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n", | ||
1045 | __func__, mf->code, mf->width, mf->height); | ||
1046 | |||
834 | /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */ | 1047 | /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */ |
835 | switch (pix->pixelformat) { | 1048 | switch (mf->code) { |
836 | case V4L2_PIX_FMT_YUYV: | 1049 | case V4L2_MBUS_FMT_YUYV8_2X8_LE: |
837 | ret = reg_write(client, RJ54N1_OUT_SEL, 0); | 1050 | ret = reg_write(client, RJ54N1_OUT_SEL, 0); |
838 | if (!ret) | 1051 | if (!ret) |
839 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); | 1052 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); |
840 | break; | 1053 | break; |
841 | case V4L2_PIX_FMT_RGB565: | 1054 | case V4L2_MBUS_FMT_YVYU8_2X8_LE: |
1055 | ret = reg_write(client, RJ54N1_OUT_SEL, 0); | ||
1056 | if (!ret) | ||
1057 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); | ||
1058 | break; | ||
1059 | case V4L2_MBUS_FMT_RGB565_2X8_LE: | ||
1060 | ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); | ||
1061 | if (!ret) | ||
1062 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); | ||
1063 | break; | ||
1064 | case V4L2_MBUS_FMT_RGB565_2X8_BE: | ||
842 | ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); | 1065 | ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); |
843 | if (!ret) | 1066 | if (!ret) |
1067 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); | ||
1068 | break; | ||
1069 | case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE: | ||
1070 | ret = reg_write(client, RJ54N1_OUT_SEL, 4); | ||
1071 | if (!ret) | ||
844 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); | 1072 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); |
1073 | if (!ret) | ||
1074 | ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); | ||
1075 | break; | ||
1076 | case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: | ||
1077 | ret = reg_write(client, RJ54N1_OUT_SEL, 4); | ||
1078 | if (!ret) | ||
1079 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); | ||
1080 | if (!ret) | ||
1081 | ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); | ||
1082 | break; | ||
1083 | case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE: | ||
1084 | ret = reg_write(client, RJ54N1_OUT_SEL, 4); | ||
1085 | if (!ret) | ||
1086 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); | ||
1087 | if (!ret) | ||
1088 | ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); | ||
1089 | break; | ||
1090 | case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE: | ||
1091 | ret = reg_write(client, RJ54N1_OUT_SEL, 4); | ||
1092 | if (!ret) | ||
1093 | ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); | ||
1094 | if (!ret) | ||
1095 | ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); | ||
1096 | break; | ||
1097 | case V4L2_MBUS_FMT_SBGGR10_1X10: | ||
1098 | ret = reg_write(client, RJ54N1_OUT_SEL, 5); | ||
845 | break; | 1099 | break; |
846 | default: | 1100 | default: |
847 | ret = -EINVAL; | 1101 | ret = -EINVAL; |
848 | } | 1102 | } |
849 | 1103 | ||
1104 | /* Special case: a raw mode with 10 bits of data per clock tick */ | ||
1105 | if (!ret) | ||
1106 | ret = reg_set(client, RJ54N1_OCLK_SEL_EN, | ||
1107 | (mf->code == V4L2_MBUS_FMT_SBGGR10_1X10) << 1, 2); | ||
1108 | |||
850 | if (ret < 0) | 1109 | if (ret < 0) |
851 | return ret; | 1110 | return ret; |
852 | 1111 | ||
853 | /* Supported scales 1:1 - 1:16 */ | 1112 | /* Supported scales 1:1 >= scale > 1:16 */ |
854 | if (pix->width < input_w / 16) | 1113 | max_w = mf->width * (16 * 1024 - 1) / 1024; |
855 | pix->width = input_w / 16; | 1114 | if (input_w > max_w) |
856 | if (pix->height < input_h / 16) | 1115 | input_w = max_w; |
857 | pix->height = input_h / 16; | 1116 | max_h = mf->height * (16 * 1024 - 1) / 1024; |
1117 | if (input_h > max_h) | ||
1118 | input_h = max_h; | ||
858 | 1119 | ||
859 | output_w = pix->width; | 1120 | output_w = mf->width; |
860 | output_h = pix->height; | 1121 | output_h = mf->height; |
861 | 1122 | ||
862 | ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h); | 1123 | ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h); |
863 | if (ret < 0) | 1124 | if (ret < 0) |
864 | return ret; | 1125 | return ret; |
865 | 1126 | ||
866 | rj54n1->fourcc = pix->pixelformat; | 1127 | fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts, |
1128 | ARRAY_SIZE(rj54n1_colour_fmts)); | ||
1129 | |||
1130 | rj54n1->fmt = fmt; | ||
867 | rj54n1->resize = ret; | 1131 | rj54n1->resize = ret; |
868 | rj54n1->rect.width = input_w; | 1132 | rj54n1->rect.width = input_w; |
869 | rj54n1->rect.height = input_h; | 1133 | rj54n1->rect.height = input_h; |
870 | rj54n1->width = output_w; | 1134 | rj54n1->width = output_w; |
871 | rj54n1->height = output_h; | 1135 | rj54n1->height = output_h; |
872 | 1136 | ||
873 | pix->width = output_w; | 1137 | mf->width = output_w; |
874 | pix->height = output_h; | 1138 | mf->height = output_h; |
875 | pix->field = V4L2_FIELD_NONE; | 1139 | mf->field = V4L2_FIELD_NONE; |
1140 | mf->colorspace = fmt->colorspace; | ||
876 | 1141 | ||
877 | return ret; | 1142 | return 0; |
878 | } | 1143 | } |
879 | 1144 | ||
880 | static int rj54n1_g_chip_ident(struct v4l2_subdev *sd, | 1145 | static int rj54n1_g_chip_ident(struct v4l2_subdev *sd, |
@@ -963,6 +1228,14 @@ static const struct v4l2_queryctrl rj54n1_controls[] = { | |||
963 | .step = 1, | 1228 | .step = 1, |
964 | .default_value = 66, | 1229 | .default_value = 66, |
965 | .flags = V4L2_CTRL_FLAG_SLIDER, | 1230 | .flags = V4L2_CTRL_FLAG_SLIDER, |
1231 | }, { | ||
1232 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
1233 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1234 | .name = "Auto white balance", | ||
1235 | .minimum = 0, | ||
1236 | .maximum = 1, | ||
1237 | .step = 1, | ||
1238 | .default_value = 1, | ||
966 | }, | 1239 | }, |
967 | }; | 1240 | }; |
968 | 1241 | ||
@@ -976,6 +1249,7 @@ static struct soc_camera_ops rj54n1_ops = { | |||
976 | static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 1249 | static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
977 | { | 1250 | { |
978 | struct i2c_client *client = sd->priv; | 1251 | struct i2c_client *client = sd->priv; |
1252 | struct rj54n1 *rj54n1 = to_rj54n1(client); | ||
979 | int data; | 1253 | int data; |
980 | 1254 | ||
981 | switch (ctrl->id) { | 1255 | switch (ctrl->id) { |
@@ -998,6 +1272,9 @@ static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
998 | 1272 | ||
999 | ctrl->value = data / 2; | 1273 | ctrl->value = data / 2; |
1000 | break; | 1274 | break; |
1275 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
1276 | ctrl->value = rj54n1->auto_wb; | ||
1277 | break; | ||
1001 | } | 1278 | } |
1002 | 1279 | ||
1003 | return 0; | 1280 | return 0; |
@@ -1007,6 +1284,7 @@ static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
1007 | { | 1284 | { |
1008 | int data; | 1285 | int data; |
1009 | struct i2c_client *client = sd->priv; | 1286 | struct i2c_client *client = sd->priv; |
1287 | struct rj54n1 *rj54n1 = to_rj54n1(client); | ||
1010 | const struct v4l2_queryctrl *qctrl; | 1288 | const struct v4l2_queryctrl *qctrl; |
1011 | 1289 | ||
1012 | qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id); | 1290 | qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id); |
@@ -1037,6 +1315,13 @@ static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
1037 | else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0) | 1315 | else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0) |
1038 | return -EIO; | 1316 | return -EIO; |
1039 | break; | 1317 | break; |
1318 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
1319 | /* Auto WB area - whole image */ | ||
1320 | if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->value << 7, | ||
1321 | 0x80) < 0) | ||
1322 | return -EIO; | ||
1323 | rj54n1->auto_wb = ctrl->value; | ||
1324 | break; | ||
1040 | } | 1325 | } |
1041 | 1326 | ||
1042 | return 0; | 1327 | return 0; |
@@ -1054,10 +1339,12 @@ static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = { | |||
1054 | 1339 | ||
1055 | static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { | 1340 | static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { |
1056 | .s_stream = rj54n1_s_stream, | 1341 | .s_stream = rj54n1_s_stream, |
1057 | .s_fmt = rj54n1_s_fmt, | 1342 | .s_mbus_fmt = rj54n1_s_fmt, |
1058 | .g_fmt = rj54n1_g_fmt, | 1343 | .g_mbus_fmt = rj54n1_g_fmt, |
1059 | .try_fmt = rj54n1_try_fmt, | 1344 | .try_mbus_fmt = rj54n1_try_fmt, |
1345 | .enum_mbus_fmt = rj54n1_enum_fmt, | ||
1060 | .g_crop = rj54n1_g_crop, | 1346 | .g_crop = rj54n1_g_crop, |
1347 | .s_crop = rj54n1_s_crop, | ||
1061 | .cropcap = rj54n1_cropcap, | 1348 | .cropcap = rj54n1_cropcap, |
1062 | }; | 1349 | }; |
1063 | 1350 | ||
@@ -1066,21 +1353,13 @@ static struct v4l2_subdev_ops rj54n1_subdev_ops = { | |||
1066 | .video = &rj54n1_subdev_video_ops, | 1353 | .video = &rj54n1_subdev_video_ops, |
1067 | }; | 1354 | }; |
1068 | 1355 | ||
1069 | static int rj54n1_pin_config(struct i2c_client *client) | ||
1070 | { | ||
1071 | /* | ||
1072 | * Experimentally found out IOCTRL wired to 0. TODO: add to platform | ||
1073 | * data: 0 or 1 << 7. | ||
1074 | */ | ||
1075 | return reg_write(client, RJ54N1_IOC, 0); | ||
1076 | } | ||
1077 | |||
1078 | /* | 1356 | /* |
1079 | * Interface active, can use i2c. If it fails, it can indeed mean, that | 1357 | * Interface active, can use i2c. If it fails, it can indeed mean, that |
1080 | * this wasn't our capture interface, so, we wait for the right one | 1358 | * this wasn't our capture interface, so, we wait for the right one |
1081 | */ | 1359 | */ |
1082 | static int rj54n1_video_probe(struct soc_camera_device *icd, | 1360 | static int rj54n1_video_probe(struct soc_camera_device *icd, |
1083 | struct i2c_client *client) | 1361 | struct i2c_client *client, |
1362 | struct rj54n1_pdata *priv) | ||
1084 | { | 1363 | { |
1085 | int data1, data2; | 1364 | int data1, data2; |
1086 | int ret; | 1365 | int ret; |
@@ -1101,7 +1380,8 @@ static int rj54n1_video_probe(struct soc_camera_device *icd, | |||
1101 | goto ei2c; | 1380 | goto ei2c; |
1102 | } | 1381 | } |
1103 | 1382 | ||
1104 | ret = rj54n1_pin_config(client); | 1383 | /* Configure IOCTL polarity from the platform data: 0 or 1 << 7. */ |
1384 | ret = reg_write(client, RJ54N1_IOC, priv->ioctl_high << 7); | ||
1105 | if (ret < 0) | 1385 | if (ret < 0) |
1106 | goto ei2c; | 1386 | goto ei2c; |
1107 | 1387 | ||
@@ -1119,6 +1399,7 @@ static int rj54n1_probe(struct i2c_client *client, | |||
1119 | struct soc_camera_device *icd = client->dev.platform_data; | 1399 | struct soc_camera_device *icd = client->dev.platform_data; |
1120 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 1400 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
1121 | struct soc_camera_link *icl; | 1401 | struct soc_camera_link *icl; |
1402 | struct rj54n1_pdata *rj54n1_priv; | ||
1122 | int ret; | 1403 | int ret; |
1123 | 1404 | ||
1124 | if (!icd) { | 1405 | if (!icd) { |
@@ -1127,11 +1408,13 @@ static int rj54n1_probe(struct i2c_client *client, | |||
1127 | } | 1408 | } |
1128 | 1409 | ||
1129 | icl = to_soc_camera_link(icd); | 1410 | icl = to_soc_camera_link(icd); |
1130 | if (!icl) { | 1411 | if (!icl || !icl->priv) { |
1131 | dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n"); | 1412 | dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n"); |
1132 | return -EINVAL; | 1413 | return -EINVAL; |
1133 | } | 1414 | } |
1134 | 1415 | ||
1416 | rj54n1_priv = icl->priv; | ||
1417 | |||
1135 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 1418 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
1136 | dev_warn(&adapter->dev, | 1419 | dev_warn(&adapter->dev, |
1137 | "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n"); | 1420 | "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE\n"); |
@@ -1153,10 +1436,12 @@ static int rj54n1_probe(struct i2c_client *client, | |||
1153 | rj54n1->rect.height = RJ54N1_MAX_HEIGHT; | 1436 | rj54n1->rect.height = RJ54N1_MAX_HEIGHT; |
1154 | rj54n1->width = RJ54N1_MAX_WIDTH; | 1437 | rj54n1->width = RJ54N1_MAX_WIDTH; |
1155 | rj54n1->height = RJ54N1_MAX_HEIGHT; | 1438 | rj54n1->height = RJ54N1_MAX_HEIGHT; |
1156 | rj54n1->fourcc = V4L2_PIX_FMT_YUYV; | 1439 | rj54n1->fmt = &rj54n1_colour_fmts[0]; |
1157 | rj54n1->resize = 1024; | 1440 | rj54n1->resize = 1024; |
1441 | rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) / | ||
1442 | (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1); | ||
1158 | 1443 | ||
1159 | ret = rj54n1_video_probe(icd, client); | 1444 | ret = rj54n1_video_probe(icd, client, rj54n1_priv); |
1160 | if (ret < 0) { | 1445 | if (ret < 0) { |
1161 | icd->ops = NULL; | 1446 | icd->ops = NULL; |
1162 | i2c_set_clientdata(client, NULL); | 1447 | i2c_set_clientdata(client, NULL); |
@@ -1164,9 +1449,6 @@ static int rj54n1_probe(struct i2c_client *client, | |||
1164 | return ret; | 1449 | return ret; |
1165 | } | 1450 | } |
1166 | 1451 | ||
1167 | icd->formats = rj54n1_colour_formats; | ||
1168 | icd->num_formats = ARRAY_SIZE(rj54n1_colour_formats); | ||
1169 | |||
1170 | return ret; | 1452 | return ret; |
1171 | } | 1453 | } |
1172 | 1454 | ||
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 41765f3c7c2..fb742f1ae71 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -233,7 +233,6 @@ struct s2255_dev { | |||
233 | 233 | ||
234 | struct s2255_dmaqueue vidq[MAX_CHANNELS]; | 234 | struct s2255_dmaqueue vidq[MAX_CHANNELS]; |
235 | struct video_device *vdev[MAX_CHANNELS]; | 235 | struct video_device *vdev[MAX_CHANNELS]; |
236 | struct list_head s2255_devlist; | ||
237 | struct timer_list timer; | 236 | struct timer_list timer; |
238 | struct s2255_fw *fw_data; | 237 | struct s2255_fw *fw_data; |
239 | struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; | 238 | struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; |
@@ -313,8 +312,6 @@ struct s2255_fh { | |||
313 | /* Channels on box are in reverse order */ | 312 | /* Channels on box are in reverse order */ |
314 | static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0}; | 313 | static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0}; |
315 | 314 | ||
316 | static LIST_HEAD(s2255_devlist); | ||
317 | |||
318 | static int debug; | 315 | static int debug; |
319 | static int *s2255_debug = &debug; | 316 | static int *s2255_debug = &debug; |
320 | 317 | ||
@@ -1533,32 +1530,24 @@ static int vidioc_s_parm(struct file *file, void *priv, | |||
1533 | } | 1530 | } |
1534 | static int s2255_open(struct file *file) | 1531 | static int s2255_open(struct file *file) |
1535 | { | 1532 | { |
1536 | int minor = video_devdata(file)->minor; | 1533 | struct video_device *vdev = video_devdata(file); |
1537 | struct s2255_dev *h, *dev = NULL; | 1534 | struct s2255_dev *dev = video_drvdata(file); |
1538 | struct s2255_fh *fh; | 1535 | struct s2255_fh *fh; |
1539 | struct list_head *list; | 1536 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1540 | enum v4l2_buf_type type = 0; | ||
1541 | int i = 0; | 1537 | int i = 0; |
1542 | int cur_channel = -1; | 1538 | int cur_channel = -1; |
1543 | int state; | 1539 | int state; |
1544 | dprintk(1, "s2255: open called (minor=%d)\n", minor); | 1540 | |
1541 | dprintk(1, "s2255: open called (dev=%s)\n", | ||
1542 | video_device_node_name(vdev)); | ||
1545 | 1543 | ||
1546 | lock_kernel(); | 1544 | lock_kernel(); |
1547 | list_for_each(list, &s2255_devlist) { | ||
1548 | h = list_entry(list, struct s2255_dev, s2255_devlist); | ||
1549 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
1550 | if (h->vdev[i]->minor == minor) { | ||
1551 | cur_channel = i; | ||
1552 | dev = h; | ||
1553 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1554 | } | ||
1555 | } | ||
1556 | } | ||
1557 | 1545 | ||
1558 | if ((NULL == dev) || (cur_channel == -1)) { | 1546 | for (i = 0; i < MAX_CHANNELS; i++) { |
1559 | unlock_kernel(); | 1547 | if (dev->vdev[i] == vdev) { |
1560 | printk(KERN_INFO "s2255: openv4l no dev\n"); | 1548 | cur_channel = i; |
1561 | return -ENODEV; | 1549 | break; |
1550 | } | ||
1562 | } | 1551 | } |
1563 | 1552 | ||
1564 | if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) { | 1553 | if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) { |
@@ -1662,8 +1651,9 @@ static int s2255_open(struct file *file) | |||
1662 | for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) | 1651 | for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) |
1663 | qctl_regs[i] = s2255_qctrl[i].default_value; | 1652 | qctl_regs[i] = s2255_qctrl[i].default_value; |
1664 | 1653 | ||
1665 | dprintk(1, "s2255drv: open minor=%d type=%s users=%d\n", | 1654 | dprintk(1, "s2255drv: open dev=%s type=%s users=%d\n", |
1666 | minor, v4l2_type_names[type], dev->users[cur_channel]); | 1655 | video_device_node_name(vdev), v4l2_type_names[type], |
1656 | dev->users[cur_channel]); | ||
1667 | dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", | 1657 | dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", |
1668 | (unsigned long)fh, (unsigned long)dev, | 1658 | (unsigned long)fh, (unsigned long)dev, |
1669 | (unsigned long)&dev->vidq[cur_channel]); | 1659 | (unsigned long)&dev->vidq[cur_channel]); |
@@ -1699,7 +1689,6 @@ static unsigned int s2255_poll(struct file *file, | |||
1699 | static void s2255_destroy(struct kref *kref) | 1689 | static void s2255_destroy(struct kref *kref) |
1700 | { | 1690 | { |
1701 | struct s2255_dev *dev = to_s2255_dev(kref); | 1691 | struct s2255_dev *dev = to_s2255_dev(kref); |
1702 | struct list_head *list; | ||
1703 | int i; | 1692 | int i; |
1704 | if (!dev) { | 1693 | if (!dev) { |
1705 | printk(KERN_ERR "s2255drv: kref problem\n"); | 1694 | printk(KERN_ERR "s2255drv: kref problem\n"); |
@@ -1733,10 +1722,6 @@ static void s2255_destroy(struct kref *kref) | |||
1733 | usb_put_dev(dev->udev); | 1722 | usb_put_dev(dev->udev); |
1734 | dprintk(1, "%s", __func__); | 1723 | dprintk(1, "%s", __func__); |
1735 | 1724 | ||
1736 | while (!list_empty(&s2255_devlist)) { | ||
1737 | list = s2255_devlist.next; | ||
1738 | list_del(list); | ||
1739 | } | ||
1740 | mutex_unlock(&dev->open_lock); | 1725 | mutex_unlock(&dev->open_lock); |
1741 | kfree(dev); | 1726 | kfree(dev); |
1742 | } | 1727 | } |
@@ -1745,7 +1730,8 @@ static int s2255_close(struct file *file) | |||
1745 | { | 1730 | { |
1746 | struct s2255_fh *fh = file->private_data; | 1731 | struct s2255_fh *fh = file->private_data; |
1747 | struct s2255_dev *dev = fh->dev; | 1732 | struct s2255_dev *dev = fh->dev; |
1748 | int minor = video_devdata(file)->minor; | 1733 | struct video_device *vdev = video_devdata(file); |
1734 | |||
1749 | if (!dev) | 1735 | if (!dev) |
1750 | return -ENODEV; | 1736 | return -ENODEV; |
1751 | 1737 | ||
@@ -1765,8 +1751,8 @@ static int s2255_close(struct file *file) | |||
1765 | mutex_unlock(&dev->open_lock); | 1751 | mutex_unlock(&dev->open_lock); |
1766 | 1752 | ||
1767 | kref_put(&dev->kref, s2255_destroy); | 1753 | kref_put(&dev->kref, s2255_destroy); |
1768 | dprintk(1, "s2255: close called (minor=%d, users=%d)\n", | 1754 | dprintk(1, "s2255: close called (dev=%s, users=%d)\n", |
1769 | minor, dev->users[fh->channel]); | 1755 | video_device_node_name(vdev), dev->users[fh->channel]); |
1770 | kfree(fh); | 1756 | kfree(fh); |
1771 | return 0; | 1757 | return 0; |
1772 | } | 1758 | } |
@@ -1830,7 +1816,6 @@ static struct video_device template = { | |||
1830 | .name = "s2255v", | 1816 | .name = "s2255v", |
1831 | .fops = &s2255_fops_v4l, | 1817 | .fops = &s2255_fops_v4l, |
1832 | .ioctl_ops = &s2255_ioctl_ops, | 1818 | .ioctl_ops = &s2255_ioctl_ops, |
1833 | .minor = -1, | ||
1834 | .release = video_device_release, | 1819 | .release = video_device_release, |
1835 | .tvnorms = S2255_NORMS, | 1820 | .tvnorms = S2255_NORMS, |
1836 | .current_norm = V4L2_STD_NTSC_M, | 1821 | .current_norm = V4L2_STD_NTSC_M, |
@@ -1843,7 +1828,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1843 | int cur_nr = video_nr; | 1828 | int cur_nr = video_nr; |
1844 | 1829 | ||
1845 | /* initialize all video 4 linux */ | 1830 | /* initialize all video 4 linux */ |
1846 | list_add_tail(&dev->s2255_devlist, &s2255_devlist); | ||
1847 | /* register 4 video devices */ | 1831 | /* register 4 video devices */ |
1848 | for (i = 0; i < MAX_CHANNELS; i++) { | 1832 | for (i = 0; i < MAX_CHANNELS; i++) { |
1849 | INIT_LIST_HEAD(&dev->vidq[i].active); | 1833 | INIT_LIST_HEAD(&dev->vidq[i].active); |
@@ -1853,6 +1837,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1853 | dev->vdev[i] = video_device_alloc(); | 1837 | dev->vdev[i] = video_device_alloc(); |
1854 | memcpy(dev->vdev[i], &template, sizeof(struct video_device)); | 1838 | memcpy(dev->vdev[i], &template, sizeof(struct video_device)); |
1855 | dev->vdev[i]->parent = &dev->interface->dev; | 1839 | dev->vdev[i]->parent = &dev->interface->dev; |
1840 | video_set_drvdata(dev->vdev[i], dev); | ||
1856 | if (video_nr == -1) | 1841 | if (video_nr == -1) |
1857 | ret = video_register_device(dev->vdev[i], | 1842 | ret = video_register_device(dev->vdev[i], |
1858 | VFL_TYPE_GRABBER, | 1843 | VFL_TYPE_GRABBER, |
@@ -1880,7 +1865,7 @@ static void s2255_exit_v4l(struct s2255_dev *dev) | |||
1880 | 1865 | ||
1881 | int i; | 1866 | int i; |
1882 | for (i = 0; i < MAX_CHANNELS; i++) { | 1867 | for (i = 0; i < MAX_CHANNELS; i++) { |
1883 | if (-1 != dev->vdev[i]->minor) { | 1868 | if (video_is_registered(dev->vdev[i])) { |
1884 | video_unregister_device(dev->vdev[i]); | 1869 | video_unregister_device(dev->vdev[i]); |
1885 | printk(KERN_INFO "s2255 unregistered\n"); | 1870 | printk(KERN_INFO "s2255 unregistered\n"); |
1886 | } else { | 1871 | } else { |
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index b624a4c01fd..5ab6a0f901c 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c | |||
@@ -1036,7 +1036,6 @@ static struct video_device saa_template = | |||
1036 | .name = "saa5246a", | 1036 | .name = "saa5246a", |
1037 | .fops = &saa_fops, | 1037 | .fops = &saa_fops, |
1038 | .release = video_device_release, | 1038 | .release = video_device_release, |
1039 | .minor = -1, | ||
1040 | }; | 1039 | }; |
1041 | 1040 | ||
1042 | static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) | 1041 | static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 7e40d6d99dd..03f572708b8 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -7211,9 +7211,31 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
7211 | } | 7211 | } |
7212 | case SAA7134_BOARD_FLYDVB_TRIO: | 7212 | case SAA7134_BOARD_FLYDVB_TRIO: |
7213 | { | 7213 | { |
7214 | u8 temp = 0; | ||
7215 | int rc; | ||
7214 | u8 data[] = { 0x3c, 0x33, 0x62}; | 7216 | u8 data[] = { 0x3c, 0x33, 0x62}; |
7215 | struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)}; | 7217 | struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)}; |
7216 | i2c_transfer(&dev->i2c_adap, &msg, 1); | 7218 | i2c_transfer(&dev->i2c_adap, &msg, 1); |
7219 | |||
7220 | /* | ||
7221 | * send weak up message to pic16C505 chip | ||
7222 | * @ LifeView FlyDVB Trio | ||
7223 | */ | ||
7224 | msg.buf = &temp; | ||
7225 | msg.addr = 0x0b; | ||
7226 | msg.len = 1; | ||
7227 | if (1 != i2c_transfer(&dev->i2c_adap, &msg, 1)) { | ||
7228 | printk(KERN_WARNING "%s: send wake up byte to pic16C505" | ||
7229 | "(IR chip) failed\n", dev->name); | ||
7230 | } else { | ||
7231 | msg.flags = I2C_M_RD; | ||
7232 | rc = i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
7233 | printk(KERN_INFO "%s: probe IR chip @ i2c 0x%02x: %s\n", | ||
7234 | dev->name, msg.addr, | ||
7235 | (1 == rc) ? "yes" : "no"); | ||
7236 | if (rc == 1) | ||
7237 | dev->has_remote = SAA7134_REMOTE_I2C; | ||
7238 | } | ||
7217 | break; | 7239 | break; |
7218 | } | 7240 | } |
7219 | case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: | 7241 | case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 0ba7f5af0fc..9f85e917f9f 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -797,27 +797,28 @@ static struct video_device *vdev_init(struct saa7134_dev *dev, | |||
797 | vfd->debug = video_debug; | 797 | vfd->debug = video_debug; |
798 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", | 798 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", |
799 | dev->name, type, saa7134_boards[dev->board].name); | 799 | dev->name, type, saa7134_boards[dev->board].name); |
800 | video_set_drvdata(vfd, dev); | ||
800 | return vfd; | 801 | return vfd; |
801 | } | 802 | } |
802 | 803 | ||
803 | static void saa7134_unregister_video(struct saa7134_dev *dev) | 804 | static void saa7134_unregister_video(struct saa7134_dev *dev) |
804 | { | 805 | { |
805 | if (dev->video_dev) { | 806 | if (dev->video_dev) { |
806 | if (-1 != dev->video_dev->minor) | 807 | if (video_is_registered(dev->video_dev)) |
807 | video_unregister_device(dev->video_dev); | 808 | video_unregister_device(dev->video_dev); |
808 | else | 809 | else |
809 | video_device_release(dev->video_dev); | 810 | video_device_release(dev->video_dev); |
810 | dev->video_dev = NULL; | 811 | dev->video_dev = NULL; |
811 | } | 812 | } |
812 | if (dev->vbi_dev) { | 813 | if (dev->vbi_dev) { |
813 | if (-1 != dev->vbi_dev->minor) | 814 | if (video_is_registered(dev->vbi_dev)) |
814 | video_unregister_device(dev->vbi_dev); | 815 | video_unregister_device(dev->vbi_dev); |
815 | else | 816 | else |
816 | video_device_release(dev->vbi_dev); | 817 | video_device_release(dev->vbi_dev); |
817 | dev->vbi_dev = NULL; | 818 | dev->vbi_dev = NULL; |
818 | } | 819 | } |
819 | if (dev->radio_dev) { | 820 | if (dev->radio_dev) { |
820 | if (-1 != dev->radio_dev->minor) | 821 | if (video_is_registered(dev->radio_dev)) |
821 | video_unregister_device(dev->radio_dev); | 822 | video_unregister_device(dev->radio_dev); |
822 | else | 823 | else |
823 | video_device_release(dev->radio_dev); | 824 | video_device_release(dev->radio_dev); |
@@ -1046,8 +1047,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1046 | dev->name); | 1047 | dev->name); |
1047 | goto fail4; | 1048 | goto fail4; |
1048 | } | 1049 | } |
1049 | printk(KERN_INFO "%s: registered device video%d [v4l2]\n", | 1050 | printk(KERN_INFO "%s: registered device %s [v4l2]\n", |
1050 | dev->name, dev->video_dev->num); | 1051 | dev->name, video_device_node_name(dev->video_dev)); |
1051 | 1052 | ||
1052 | dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); | 1053 | dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); |
1053 | 1054 | ||
@@ -1055,8 +1056,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1055 | vbi_nr[dev->nr]); | 1056 | vbi_nr[dev->nr]); |
1056 | if (err < 0) | 1057 | if (err < 0) |
1057 | goto fail4; | 1058 | goto fail4; |
1058 | printk(KERN_INFO "%s: registered device vbi%d\n", | 1059 | printk(KERN_INFO "%s: registered device %s\n", |
1059 | dev->name, dev->vbi_dev->num); | 1060 | dev->name, video_device_node_name(dev->vbi_dev)); |
1060 | 1061 | ||
1061 | if (card_has_radio(dev)) { | 1062 | if (card_has_radio(dev)) { |
1062 | dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio"); | 1063 | dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio"); |
@@ -1064,8 +1065,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1064 | radio_nr[dev->nr]); | 1065 | radio_nr[dev->nr]); |
1065 | if (err < 0) | 1066 | if (err < 0) |
1066 | goto fail4; | 1067 | goto fail4; |
1067 | printk(KERN_INFO "%s: registered device radio%d\n", | 1068 | printk(KERN_INFO "%s: registered device %s\n", |
1068 | dev->name, dev->radio_dev->num); | 1069 | dev->name, video_device_node_name(dev->radio_dev)); |
1069 | } | 1070 | } |
1070 | 1071 | ||
1071 | /* everything worked */ | 1072 | /* everything worked */ |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 296788c3bf0..7dfecfc6017 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -86,19 +86,11 @@ static int ts_init_encoder(struct saa7134_dev* dev) | |||
86 | 86 | ||
87 | static int ts_open(struct file *file) | 87 | static int ts_open(struct file *file) |
88 | { | 88 | { |
89 | int minor = video_devdata(file)->minor; | 89 | struct video_device *vdev = video_devdata(file); |
90 | struct saa7134_dev *dev; | 90 | struct saa7134_dev *dev = video_drvdata(file); |
91 | int err; | 91 | int err; |
92 | 92 | ||
93 | lock_kernel(); | 93 | dprintk("open dev=%s\n", video_device_node_name(vdev)); |
94 | list_for_each_entry(dev, &saa7134_devlist, devlist) | ||
95 | if (dev->empress_dev && dev->empress_dev->minor == minor) | ||
96 | goto found; | ||
97 | unlock_kernel(); | ||
98 | return -ENODEV; | ||
99 | found: | ||
100 | |||
101 | dprintk("open minor=%d\n",minor); | ||
102 | err = -EBUSY; | 94 | err = -EBUSY; |
103 | if (!mutex_trylock(&dev->empress_tsq.vb_lock)) | 95 | if (!mutex_trylock(&dev->empress_tsq.vb_lock)) |
104 | goto done; | 96 | goto done; |
@@ -489,7 +481,6 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { | |||
489 | static struct video_device saa7134_empress_template = { | 481 | static struct video_device saa7134_empress_template = { |
490 | .name = "saa7134-empress", | 482 | .name = "saa7134-empress", |
491 | .fops = &ts_fops, | 483 | .fops = &ts_fops, |
492 | .minor = -1, | ||
493 | .ioctl_ops = &ts_ioctl_ops, | 484 | .ioctl_ops = &ts_ioctl_ops, |
494 | 485 | ||
495 | .tvnorms = SAA7134_NORMS, | 486 | .tvnorms = SAA7134_NORMS, |
@@ -531,6 +522,7 @@ static int empress_init(struct saa7134_dev *dev) | |||
531 | 522 | ||
532 | INIT_WORK(&dev->empress_workqueue, empress_signal_update); | 523 | INIT_WORK(&dev->empress_workqueue, empress_signal_update); |
533 | 524 | ||
525 | video_set_drvdata(dev->empress_dev, dev); | ||
534 | err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, | 526 | err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, |
535 | empress_nr[dev->nr]); | 527 | empress_nr[dev->nr]); |
536 | if (err < 0) { | 528 | if (err < 0) { |
@@ -540,8 +532,8 @@ static int empress_init(struct saa7134_dev *dev) | |||
540 | dev->empress_dev = NULL; | 532 | dev->empress_dev = NULL; |
541 | return err; | 533 | return err; |
542 | } | 534 | } |
543 | printk(KERN_INFO "%s: registered device video%d [mpeg]\n", | 535 | printk(KERN_INFO "%s: registered device %s [mpeg]\n", |
544 | dev->name, dev->empress_dev->num); | 536 | dev->name, video_device_node_name(dev->empress_dev)); |
545 | 537 | ||
546 | videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops, | 538 | videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops, |
547 | &dev->pci->dev, &dev->slock, | 539 | &dev->pci->dev, &dev->slock, |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 744918b1cd4..f8e985989ca 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -127,6 +127,61 @@ static int build_key(struct saa7134_dev *dev) | |||
127 | 127 | ||
128 | /* --------------------- Chip specific I2C key builders ----------------- */ | 128 | /* --------------------- Chip specific I2C key builders ----------------- */ |
129 | 129 | ||
130 | static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
131 | { | ||
132 | int gpio; | ||
133 | int attempt = 0; | ||
134 | unsigned char b; | ||
135 | |||
136 | /* We need this to access GPI Used by the saa_readl macro. */ | ||
137 | struct saa7134_dev *dev = ir->c->adapter->algo_data; | ||
138 | |||
139 | if (dev == NULL) { | ||
140 | dprintk("get_key_flydvb_trio: " | ||
141 | "gir->c->adapter->algo_data is NULL!\n"); | ||
142 | return -EIO; | ||
143 | } | ||
144 | |||
145 | /* rising SAA7134_GPIGPRESCAN reads the status */ | ||
146 | saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
147 | saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); | ||
148 | |||
149 | gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); | ||
150 | |||
151 | if (0x40000 & ~gpio) | ||
152 | return 0; /* No button press */ | ||
153 | |||
154 | /* No button press - only before first key pressed */ | ||
155 | if (b == 0xFF) | ||
156 | return 0; | ||
157 | |||
158 | /* poll IR chip */ | ||
159 | /* weak up the IR chip */ | ||
160 | b = 0; | ||
161 | |||
162 | while (1 != i2c_master_send(ir->c, &b, 1)) { | ||
163 | if ((attempt++) < 10) { | ||
164 | /* | ||
165 | * wait a bit for next attempt - | ||
166 | * I don't know how make it better | ||
167 | */ | ||
168 | msleep(10); | ||
169 | continue; | ||
170 | } | ||
171 | i2cdprintk("send wake up byte to pic16C505 (IR chip)" | ||
172 | "failed %dx\n", attempt); | ||
173 | return -EIO; | ||
174 | } | ||
175 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | ||
176 | i2cdprintk("read error\n"); | ||
177 | return -EIO; | ||
178 | } | ||
179 | |||
180 | *ir_key = b; | ||
181 | *ir_raw = b; | ||
182 | return 1; | ||
183 | } | ||
184 | |||
130 | static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, | 185 | static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, |
131 | u32 *ir_raw) | 186 | u32 *ir_raw) |
132 | { | 187 | { |
@@ -622,6 +677,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
622 | mask_keyup = 0x020000; | 677 | mask_keyup = 0x020000; |
623 | polling = 50; /* ms */ | 678 | polling = 50; /* ms */ |
624 | break; | 679 | break; |
680 | break; | ||
625 | } | 681 | } |
626 | if (NULL == ir_codes) { | 682 | if (NULL == ir_codes) { |
627 | printk("%s: Oops: IR config error [card=%d]\n", | 683 | printk("%s: Oops: IR config error [card=%d]\n", |
@@ -652,7 +708,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
652 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", | 708 | snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", |
653 | pci_name(dev->pci)); | 709 | pci_name(dev->pci)); |
654 | 710 | ||
655 | err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); | 711 | err = ir_input_init(input_dev, &ir->ir, ir_type); |
656 | if (err < 0) | 712 | if (err < 0) |
657 | goto err_out_free; | 713 | goto err_out_free; |
658 | 714 | ||
@@ -672,7 +728,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
672 | dev->remote = ir; | 728 | dev->remote = ir; |
673 | saa7134_ir_start(dev, ir); | 729 | saa7134_ir_start(dev, ir); |
674 | 730 | ||
675 | err = input_register_device(ir->dev); | 731 | err = ir_input_register(ir->dev, ir_codes); |
676 | if (err) | 732 | if (err) |
677 | goto err_out_stop; | 733 | goto err_out_stop; |
678 | 734 | ||
@@ -686,8 +742,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
686 | saa7134_ir_stop(dev); | 742 | saa7134_ir_stop(dev); |
687 | dev->remote = NULL; | 743 | dev->remote = NULL; |
688 | err_out_free: | 744 | err_out_free: |
689 | ir_input_free(input_dev); | ||
690 | input_free_device(input_dev); | ||
691 | kfree(ir); | 745 | kfree(ir); |
692 | return err; | 746 | return err; |
693 | } | 747 | } |
@@ -698,8 +752,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
698 | return; | 752 | return; |
699 | 753 | ||
700 | saa7134_ir_stop(dev); | 754 | saa7134_ir_stop(dev); |
701 | ir_input_free(dev->remote->dev); | 755 | ir_input_unregister(dev->remote->dev); |
702 | input_unregister_device(dev->remote->dev); | ||
703 | kfree(dev->remote); | 756 | kfree(dev->remote); |
704 | dev->remote = NULL; | 757 | dev->remote = NULL; |
705 | } | 758 | } |
@@ -788,6 +841,12 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) | |||
788 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: | 841 | case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: |
789 | info.addr = 0x40; | 842 | info.addr = 0x40; |
790 | break; | 843 | break; |
844 | case SAA7134_BOARD_FLYDVB_TRIO: | ||
845 | dev->init_data.name = "FlyDVB Trio"; | ||
846 | dev->init_data.get_key = get_key_flydvb_trio; | ||
847 | dev->init_data.ir_codes = &ir_codes_flydvb_table; | ||
848 | info.addr = 0x0b; | ||
849 | break; | ||
791 | default: | 850 | default: |
792 | dprintk("No I2C IR support for board %x\n", dev->board); | 851 | dprintk("No I2C IR support for board %x\n", dev->board); |
793 | return; | 852 | return; |
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 35f8daa3a35..cb732640ac4 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -1326,33 +1326,26 @@ static int saa7134_resource(struct saa7134_fh *fh) | |||
1326 | 1326 | ||
1327 | static int video_open(struct file *file) | 1327 | static int video_open(struct file *file) |
1328 | { | 1328 | { |
1329 | int minor = video_devdata(file)->minor; | 1329 | struct video_device *vdev = video_devdata(file); |
1330 | struct saa7134_dev *dev; | 1330 | struct saa7134_dev *dev = video_drvdata(file); |
1331 | struct saa7134_fh *fh; | 1331 | struct saa7134_fh *fh; |
1332 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1332 | enum v4l2_buf_type type = 0; |
1333 | int radio = 0; | 1333 | int radio = 0; |
1334 | 1334 | ||
1335 | mutex_lock(&saa7134_devlist_lock); | 1335 | switch (vdev->vfl_type) { |
1336 | list_for_each_entry(dev, &saa7134_devlist, devlist) { | 1336 | case VFL_TYPE_GRABBER: |
1337 | if (dev->video_dev && (dev->video_dev->minor == minor)) | 1337 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1338 | goto found; | 1338 | break; |
1339 | if (dev->radio_dev && (dev->radio_dev->minor == minor)) { | 1339 | case VFL_TYPE_VBI: |
1340 | radio = 1; | 1340 | type = V4L2_BUF_TYPE_VBI_CAPTURE; |
1341 | goto found; | 1341 | break; |
1342 | } | 1342 | case VFL_TYPE_RADIO: |
1343 | if (dev->vbi_dev && (dev->vbi_dev->minor == minor)) { | 1343 | radio = 1; |
1344 | type = V4L2_BUF_TYPE_VBI_CAPTURE; | 1344 | break; |
1345 | goto found; | ||
1346 | } | ||
1347 | } | 1345 | } |
1348 | mutex_unlock(&saa7134_devlist_lock); | ||
1349 | return -ENODEV; | ||
1350 | |||
1351 | found: | ||
1352 | mutex_unlock(&saa7134_devlist_lock); | ||
1353 | 1346 | ||
1354 | dprintk("open minor=%d radio=%d type=%s\n",minor,radio, | 1347 | dprintk("open dev=%s radio=%d type=%s\n", video_device_node_name(vdev), |
1355 | v4l2_type_names[type]); | 1348 | radio, v4l2_type_names[type]); |
1356 | 1349 | ||
1357 | /* allocate + initialize per filehandle data */ | 1350 | /* allocate + initialize per filehandle data */ |
1358 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); | 1351 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); |
@@ -2502,7 +2495,6 @@ struct video_device saa7134_video_template = { | |||
2502 | .name = "saa7134-video", | 2495 | .name = "saa7134-video", |
2503 | .fops = &video_fops, | 2496 | .fops = &video_fops, |
2504 | .ioctl_ops = &video_ioctl_ops, | 2497 | .ioctl_ops = &video_ioctl_ops, |
2505 | .minor = -1, | ||
2506 | .tvnorms = SAA7134_NORMS, | 2498 | .tvnorms = SAA7134_NORMS, |
2507 | .current_norm = V4L2_STD_PAL, | 2499 | .current_norm = V4L2_STD_PAL, |
2508 | }; | 2500 | }; |
@@ -2511,7 +2503,6 @@ struct video_device saa7134_radio_template = { | |||
2511 | .name = "saa7134-radio", | 2503 | .name = "saa7134-radio", |
2512 | .fops = &radio_fops, | 2504 | .fops = &radio_fops, |
2513 | .ioctl_ops = &radio_ioctl_ops, | 2505 | .ioctl_ops = &radio_ioctl_ops, |
2514 | .minor = -1, | ||
2515 | }; | 2506 | }; |
2516 | 2507 | ||
2517 | int saa7134_video_init1(struct saa7134_dev *dev) | 2508 | int saa7134_video_init1(struct saa7134_dev *dev) |
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index 85ffc2cba03..41d0166c0f9 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c | |||
@@ -1428,8 +1428,8 @@ static int se401_probe(struct usb_interface *intf, | |||
1428 | err("video_register_device failed"); | 1428 | err("video_register_device failed"); |
1429 | return -EIO; | 1429 | return -EIO; |
1430 | } | 1430 | } |
1431 | dev_info(&intf->dev, "registered new video device: video%d\n", | 1431 | dev_info(&intf->dev, "registered new video device: %s\n", |
1432 | se401->vdev.num); | 1432 | video_device_node_name(&se401->vdev)); |
1433 | 1433 | ||
1434 | usb_set_intfdata(intf, se401); | 1434 | usb_set_intfdata(intf, se401); |
1435 | return 0; | 1435 | return 0; |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 961e4484d72..d69363f0d8c 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <media/soc_camera.h> | 38 | #include <media/soc_camera.h> |
39 | #include <media/sh_mobile_ceu.h> | 39 | #include <media/sh_mobile_ceu.h> |
40 | #include <media/videobuf-dma-contig.h> | 40 | #include <media/videobuf-dma-contig.h> |
41 | #include <media/v4l2-mediabus.h> | ||
42 | #include <media/soc_mediabus.h> | ||
41 | 43 | ||
42 | /* register offsets for sh7722 / sh7723 */ | 44 | /* register offsets for sh7722 / sh7723 */ |
43 | 45 | ||
@@ -85,7 +87,7 @@ | |||
85 | /* per video frame buffer */ | 87 | /* per video frame buffer */ |
86 | struct sh_mobile_ceu_buffer { | 88 | struct sh_mobile_ceu_buffer { |
87 | struct videobuf_buffer vb; /* v4l buffer must be first */ | 89 | struct videobuf_buffer vb; /* v4l buffer must be first */ |
88 | const struct soc_camera_data_format *fmt; | 90 | enum v4l2_mbus_pixelcode code; |
89 | }; | 91 | }; |
90 | 92 | ||
91 | struct sh_mobile_ceu_dev { | 93 | struct sh_mobile_ceu_dev { |
@@ -105,7 +107,8 @@ struct sh_mobile_ceu_dev { | |||
105 | 107 | ||
106 | u32 cflcr; | 108 | u32 cflcr; |
107 | 109 | ||
108 | unsigned int is_interlaced:1; | 110 | enum v4l2_field field; |
111 | |||
109 | unsigned int image_mode:1; | 112 | unsigned int image_mode:1; |
110 | unsigned int is_16bit:1; | 113 | unsigned int is_16bit:1; |
111 | }; | 114 | }; |
@@ -114,8 +117,8 @@ struct sh_mobile_ceu_cam { | |||
114 | struct v4l2_rect ceu_rect; | 117 | struct v4l2_rect ceu_rect; |
115 | unsigned int cam_width; | 118 | unsigned int cam_width; |
116 | unsigned int cam_height; | 119 | unsigned int cam_height; |
117 | const struct soc_camera_data_format *extra_fmt; | 120 | const struct soc_mbus_pixelfmt *extra_fmt; |
118 | const struct soc_camera_data_format *camera_fmt; | 121 | enum v4l2_mbus_pixelcode code; |
119 | }; | 122 | }; |
120 | 123 | ||
121 | static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev) | 124 | static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev) |
@@ -197,16 +200,19 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq, | |||
197 | struct soc_camera_device *icd = vq->priv_data; | 200 | struct soc_camera_device *icd = vq->priv_data; |
198 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 201 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
199 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | 202 | struct sh_mobile_ceu_dev *pcdev = ici->priv; |
200 | int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3; | 203 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, |
204 | icd->current_fmt->host_fmt); | ||
205 | |||
206 | if (bytes_per_line < 0) | ||
207 | return bytes_per_line; | ||
201 | 208 | ||
202 | *size = PAGE_ALIGN(icd->user_width * icd->user_height * | 209 | *size = bytes_per_line * icd->user_height; |
203 | bytes_per_pixel); | ||
204 | 210 | ||
205 | if (0 == *count) | 211 | if (0 == *count) |
206 | *count = 2; | 212 | *count = 2; |
207 | 213 | ||
208 | if (pcdev->video_limit) { | 214 | if (pcdev->video_limit) { |
209 | while (*size * *count > pcdev->video_limit) | 215 | while (PAGE_ALIGN(*size) * *count > pcdev->video_limit) |
210 | (*count)--; | 216 | (*count)--; |
211 | } | 217 | } |
212 | 218 | ||
@@ -249,10 +255,13 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) | |||
249 | { | 255 | { |
250 | struct soc_camera_device *icd = pcdev->icd; | 256 | struct soc_camera_device *icd = pcdev->icd; |
251 | dma_addr_t phys_addr_top, phys_addr_bottom; | 257 | dma_addr_t phys_addr_top, phys_addr_bottom; |
258 | unsigned long top1, top2; | ||
259 | unsigned long bottom1, bottom2; | ||
252 | u32 status; | 260 | u32 status; |
253 | int ret = 0; | 261 | int ret = 0; |
254 | 262 | ||
255 | /* The hardware is _very_ picky about this sequence. Especially | 263 | /* |
264 | * The hardware is _very_ picky about this sequence. Especially | ||
256 | * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge | 265 | * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge |
257 | * several not-so-well documented interrupt sources in CETCR. | 266 | * several not-so-well documented interrupt sources in CETCR. |
258 | */ | 267 | */ |
@@ -276,25 +285,36 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) | |||
276 | if (!pcdev->active) | 285 | if (!pcdev->active) |
277 | return ret; | 286 | return ret; |
278 | 287 | ||
288 | if (V4L2_FIELD_INTERLACED_BT == pcdev->field) { | ||
289 | top1 = CDBYR; | ||
290 | top2 = CDBCR; | ||
291 | bottom1 = CDAYR; | ||
292 | bottom2 = CDACR; | ||
293 | } else { | ||
294 | top1 = CDAYR; | ||
295 | top2 = CDACR; | ||
296 | bottom1 = CDBYR; | ||
297 | bottom2 = CDBCR; | ||
298 | } | ||
299 | |||
279 | phys_addr_top = videobuf_to_dma_contig(pcdev->active); | 300 | phys_addr_top = videobuf_to_dma_contig(pcdev->active); |
280 | ceu_write(pcdev, CDAYR, phys_addr_top); | 301 | ceu_write(pcdev, top1, phys_addr_top); |
281 | if (pcdev->is_interlaced) { | 302 | if (V4L2_FIELD_NONE != pcdev->field) { |
282 | phys_addr_bottom = phys_addr_top + icd->user_width; | 303 | phys_addr_bottom = phys_addr_top + icd->user_width; |
283 | ceu_write(pcdev, CDBYR, phys_addr_bottom); | 304 | ceu_write(pcdev, bottom1, phys_addr_bottom); |
284 | } | 305 | } |
285 | 306 | ||
286 | switch (icd->current_fmt->fourcc) { | 307 | switch (icd->current_fmt->host_fmt->fourcc) { |
287 | case V4L2_PIX_FMT_NV12: | 308 | case V4L2_PIX_FMT_NV12: |
288 | case V4L2_PIX_FMT_NV21: | 309 | case V4L2_PIX_FMT_NV21: |
289 | case V4L2_PIX_FMT_NV16: | 310 | case V4L2_PIX_FMT_NV16: |
290 | case V4L2_PIX_FMT_NV61: | 311 | case V4L2_PIX_FMT_NV61: |
291 | phys_addr_top += icd->user_width * | 312 | phys_addr_top += icd->user_width * |
292 | icd->user_height; | 313 | icd->user_height; |
293 | ceu_write(pcdev, CDACR, phys_addr_top); | 314 | ceu_write(pcdev, top2, phys_addr_top); |
294 | if (pcdev->is_interlaced) { | 315 | if (V4L2_FIELD_NONE != pcdev->field) { |
295 | phys_addr_bottom = phys_addr_top + | 316 | phys_addr_bottom = phys_addr_top + icd->user_width; |
296 | icd->user_width; | 317 | ceu_write(pcdev, bottom2, phys_addr_bottom); |
297 | ceu_write(pcdev, CDBCR, phys_addr_bottom); | ||
298 | } | 318 | } |
299 | } | 319 | } |
300 | 320 | ||
@@ -310,8 +330,13 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, | |||
310 | { | 330 | { |
311 | struct soc_camera_device *icd = vq->priv_data; | 331 | struct soc_camera_device *icd = vq->priv_data; |
312 | struct sh_mobile_ceu_buffer *buf; | 332 | struct sh_mobile_ceu_buffer *buf; |
333 | int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, | ||
334 | icd->current_fmt->host_fmt); | ||
313 | int ret; | 335 | int ret; |
314 | 336 | ||
337 | if (bytes_per_line < 0) | ||
338 | return bytes_per_line; | ||
339 | |||
315 | buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); | 340 | buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); |
316 | 341 | ||
317 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, | 342 | dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, |
@@ -321,25 +346,27 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, | |||
321 | WARN_ON(!list_empty(&vb->queue)); | 346 | WARN_ON(!list_empty(&vb->queue)); |
322 | 347 | ||
323 | #ifdef DEBUG | 348 | #ifdef DEBUG |
324 | /* This can be useful if you want to see if we actually fill | 349 | /* |
325 | * the buffer with something */ | 350 | * This can be useful if you want to see if we actually fill |
351 | * the buffer with something | ||
352 | */ | ||
326 | memset((void *)vb->baddr, 0xaa, vb->bsize); | 353 | memset((void *)vb->baddr, 0xaa, vb->bsize); |
327 | #endif | 354 | #endif |
328 | 355 | ||
329 | BUG_ON(NULL == icd->current_fmt); | 356 | BUG_ON(NULL == icd->current_fmt); |
330 | 357 | ||
331 | if (buf->fmt != icd->current_fmt || | 358 | if (buf->code != icd->current_fmt->code || |
332 | vb->width != icd->user_width || | 359 | vb->width != icd->user_width || |
333 | vb->height != icd->user_height || | 360 | vb->height != icd->user_height || |
334 | vb->field != field) { | 361 | vb->field != field) { |
335 | buf->fmt = icd->current_fmt; | 362 | buf->code = icd->current_fmt->code; |
336 | vb->width = icd->user_width; | 363 | vb->width = icd->user_width; |
337 | vb->height = icd->user_height; | 364 | vb->height = icd->user_height; |
338 | vb->field = field; | 365 | vb->field = field; |
339 | vb->state = VIDEOBUF_NEEDS_INIT; | 366 | vb->state = VIDEOBUF_NEEDS_INIT; |
340 | } | 367 | } |
341 | 368 | ||
342 | vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); | 369 | vb->size = vb->height * bytes_per_line; |
343 | if (0 != vb->baddr && vb->bsize < vb->size) { | 370 | if (0 != vb->baddr && vb->bsize < vb->size) { |
344 | ret = -EINVAL; | 371 | ret = -EINVAL; |
345 | goto out; | 372 | goto out; |
@@ -456,6 +483,7 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) | |||
456 | { | 483 | { |
457 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 484 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
458 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | 485 | struct sh_mobile_ceu_dev *pcdev = ici->priv; |
486 | int ret; | ||
459 | 487 | ||
460 | if (pcdev->icd) | 488 | if (pcdev->icd) |
461 | return -EBUSY; | 489 | return -EBUSY; |
@@ -466,9 +494,11 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) | |||
466 | 494 | ||
467 | pm_runtime_get_sync(ici->v4l2_dev.dev); | 495 | pm_runtime_get_sync(ici->v4l2_dev.dev); |
468 | 496 | ||
469 | pcdev->icd = icd; | 497 | ret = sh_mobile_ceu_soft_reset(pcdev); |
498 | if (!ret) | ||
499 | pcdev->icd = icd; | ||
470 | 500 | ||
471 | return sh_mobile_ceu_soft_reset(pcdev); | 501 | return ret; |
472 | } | 502 | } |
473 | 503 | ||
474 | /* Called with .video_lock held */ | 504 | /* Called with .video_lock held */ |
@@ -558,24 +588,35 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd, | |||
558 | in_width *= 2; | 588 | in_width *= 2; |
559 | left_offset *= 2; | 589 | left_offset *= 2; |
560 | } | 590 | } |
561 | width = cdwdr_width = out_width; | 591 | width = out_width; |
592 | cdwdr_width = out_width; | ||
562 | } else { | 593 | } else { |
563 | unsigned int w_factor = (icd->current_fmt->depth + 7) >> 3; | 594 | int bytes_per_line = soc_mbus_bytes_per_line(out_width, |
595 | icd->current_fmt->host_fmt); | ||
596 | unsigned int w_factor; | ||
564 | 597 | ||
565 | width = out_width * w_factor / 2; | 598 | width = out_width; |
566 | 599 | ||
567 | if (!pcdev->is_16bit) | 600 | switch (icd->current_fmt->host_fmt->packing) { |
568 | w_factor *= 2; | 601 | case SOC_MBUS_PACKING_2X8_PADHI: |
602 | w_factor = 2; | ||
603 | break; | ||
604 | default: | ||
605 | w_factor = 1; | ||
606 | } | ||
569 | 607 | ||
570 | in_width = rect->width * w_factor / 2; | 608 | in_width = rect->width * w_factor; |
571 | left_offset = left_offset * w_factor / 2; | 609 | left_offset = left_offset * w_factor; |
572 | 610 | ||
573 | cdwdr_width = width * 2; | 611 | if (bytes_per_line < 0) |
612 | cdwdr_width = out_width; | ||
613 | else | ||
614 | cdwdr_width = bytes_per_line; | ||
574 | } | 615 | } |
575 | 616 | ||
576 | height = out_height; | 617 | height = out_height; |
577 | in_height = rect->height; | 618 | in_height = rect->height; |
578 | if (pcdev->is_interlaced) { | 619 | if (V4L2_FIELD_NONE != pcdev->field) { |
579 | height /= 2; | 620 | height /= 2; |
580 | in_height /= 2; | 621 | in_height /= 2; |
581 | top_offset /= 2; | 622 | top_offset /= 2; |
@@ -646,6 +687,23 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, | |||
646 | if (!common_flags) | 687 | if (!common_flags) |
647 | return -EINVAL; | 688 | return -EINVAL; |
648 | 689 | ||
690 | /* Make choises, based on platform preferences */ | ||
691 | if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && | ||
692 | (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { | ||
693 | if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW) | ||
694 | common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; | ||
695 | else | ||
696 | common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; | ||
697 | } | ||
698 | |||
699 | if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && | ||
700 | (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { | ||
701 | if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW) | ||
702 | common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; | ||
703 | else | ||
704 | common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; | ||
705 | } | ||
706 | |||
649 | ret = icd->ops->set_bus_param(icd, common_flags); | 707 | ret = icd->ops->set_bus_param(icd, common_flags); |
650 | if (ret < 0) | 708 | if (ret < 0) |
651 | return ret; | 709 | return ret; |
@@ -667,24 +725,24 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, | |||
667 | value = 0x00000010; /* data fetch by default */ | 725 | value = 0x00000010; /* data fetch by default */ |
668 | yuv_lineskip = 0; | 726 | yuv_lineskip = 0; |
669 | 727 | ||
670 | switch (icd->current_fmt->fourcc) { | 728 | switch (icd->current_fmt->host_fmt->fourcc) { |
671 | case V4L2_PIX_FMT_NV12: | 729 | case V4L2_PIX_FMT_NV12: |
672 | case V4L2_PIX_FMT_NV21: | 730 | case V4L2_PIX_FMT_NV21: |
673 | yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */ | 731 | yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */ |
674 | /* fall-through */ | 732 | /* fall-through */ |
675 | case V4L2_PIX_FMT_NV16: | 733 | case V4L2_PIX_FMT_NV16: |
676 | case V4L2_PIX_FMT_NV61: | 734 | case V4L2_PIX_FMT_NV61: |
677 | switch (cam->camera_fmt->fourcc) { | 735 | switch (cam->code) { |
678 | case V4L2_PIX_FMT_UYVY: | 736 | case V4L2_MBUS_FMT_YUYV8_2X8_BE: |
679 | value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */ | 737 | value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */ |
680 | break; | 738 | break; |
681 | case V4L2_PIX_FMT_VYUY: | 739 | case V4L2_MBUS_FMT_YVYU8_2X8_BE: |
682 | value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */ | 740 | value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */ |
683 | break; | 741 | break; |
684 | case V4L2_PIX_FMT_YUYV: | 742 | case V4L2_MBUS_FMT_YUYV8_2X8_LE: |
685 | value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */ | 743 | value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */ |
686 | break; | 744 | break; |
687 | case V4L2_PIX_FMT_YVYU: | 745 | case V4L2_MBUS_FMT_YVYU8_2X8_LE: |
688 | value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */ | 746 | value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */ |
689 | break; | 747 | break; |
690 | default: | 748 | default: |
@@ -692,8 +750,8 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, | |||
692 | } | 750 | } |
693 | } | 751 | } |
694 | 752 | ||
695 | if (icd->current_fmt->fourcc == V4L2_PIX_FMT_NV21 || | 753 | if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV21 || |
696 | icd->current_fmt->fourcc == V4L2_PIX_FMT_NV61) | 754 | icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61) |
697 | value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */ | 755 | value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */ |
698 | 756 | ||
699 | value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; | 757 | value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; |
@@ -702,14 +760,27 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, | |||
702 | ceu_write(pcdev, CAMCR, value); | 760 | ceu_write(pcdev, CAMCR, value); |
703 | 761 | ||
704 | ceu_write(pcdev, CAPCR, 0x00300000); | 762 | ceu_write(pcdev, CAPCR, 0x00300000); |
705 | ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0); | 763 | |
764 | switch (pcdev->field) { | ||
765 | case V4L2_FIELD_INTERLACED_TB: | ||
766 | value = 0x101; | ||
767 | break; | ||
768 | case V4L2_FIELD_INTERLACED_BT: | ||
769 | value = 0x102; | ||
770 | break; | ||
771 | default: | ||
772 | value = 0; | ||
773 | break; | ||
774 | } | ||
775 | ceu_write(pcdev, CAIFR, value); | ||
706 | 776 | ||
707 | sh_mobile_ceu_set_rect(icd, icd->user_width, icd->user_height); | 777 | sh_mobile_ceu_set_rect(icd, icd->user_width, icd->user_height); |
708 | mdelay(1); | 778 | mdelay(1); |
709 | 779 | ||
710 | ceu_write(pcdev, CFLCR, pcdev->cflcr); | 780 | ceu_write(pcdev, CFLCR, pcdev->cflcr); |
711 | 781 | ||
712 | /* A few words about byte order (observed in Big Endian mode) | 782 | /* |
783 | * A few words about byte order (observed in Big Endian mode) | ||
713 | * | 784 | * |
714 | * In data fetch mode bytes are received in chunks of 8 bytes. | 785 | * In data fetch mode bytes are received in chunks of 8 bytes. |
715 | * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first) | 786 | * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first) |
@@ -739,7 +810,8 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, | |||
739 | return 0; | 810 | return 0; |
740 | } | 811 | } |
741 | 812 | ||
742 | static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd) | 813 | static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, |
814 | unsigned char buswidth) | ||
743 | { | 815 | { |
744 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 816 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
745 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | 817 | struct sh_mobile_ceu_dev *pcdev = ici->priv; |
@@ -748,48 +820,75 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd) | |||
748 | camera_flags = icd->ops->query_bus_param(icd); | 820 | camera_flags = icd->ops->query_bus_param(icd); |
749 | common_flags = soc_camera_bus_param_compatible(camera_flags, | 821 | common_flags = soc_camera_bus_param_compatible(camera_flags, |
750 | make_bus_param(pcdev)); | 822 | make_bus_param(pcdev)); |
751 | if (!common_flags) | 823 | if (!common_flags || buswidth > 16 || |
824 | (buswidth > 8 && !(common_flags & SOCAM_DATAWIDTH_16))) | ||
752 | return -EINVAL; | 825 | return -EINVAL; |
753 | 826 | ||
754 | return 0; | 827 | return 0; |
755 | } | 828 | } |
756 | 829 | ||
757 | static const struct soc_camera_data_format sh_mobile_ceu_formats[] = { | 830 | static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = { |
758 | { | ||
759 | .name = "NV12", | ||
760 | .depth = 12, | ||
761 | .fourcc = V4L2_PIX_FMT_NV12, | ||
762 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
763 | }, | ||
764 | { | ||
765 | .name = "NV21", | ||
766 | .depth = 12, | ||
767 | .fourcc = V4L2_PIX_FMT_NV21, | ||
768 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
769 | }, | ||
770 | { | ||
771 | .name = "NV16", | ||
772 | .depth = 16, | ||
773 | .fourcc = V4L2_PIX_FMT_NV16, | ||
774 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
775 | }, | ||
776 | { | 831 | { |
777 | .name = "NV61", | 832 | .fourcc = V4L2_PIX_FMT_NV12, |
778 | .depth = 16, | 833 | .name = "NV12", |
779 | .fourcc = V4L2_PIX_FMT_NV61, | 834 | .bits_per_sample = 12, |
780 | .colorspace = V4L2_COLORSPACE_JPEG, | 835 | .packing = SOC_MBUS_PACKING_NONE, |
836 | .order = SOC_MBUS_ORDER_LE, | ||
837 | }, { | ||
838 | .fourcc = V4L2_PIX_FMT_NV21, | ||
839 | .name = "NV21", | ||
840 | .bits_per_sample = 12, | ||
841 | .packing = SOC_MBUS_PACKING_NONE, | ||
842 | .order = SOC_MBUS_ORDER_LE, | ||
843 | }, { | ||
844 | .fourcc = V4L2_PIX_FMT_NV16, | ||
845 | .name = "NV16", | ||
846 | .bits_per_sample = 16, | ||
847 | .packing = SOC_MBUS_PACKING_NONE, | ||
848 | .order = SOC_MBUS_ORDER_LE, | ||
849 | }, { | ||
850 | .fourcc = V4L2_PIX_FMT_NV61, | ||
851 | .name = "NV61", | ||
852 | .bits_per_sample = 16, | ||
853 | .packing = SOC_MBUS_PACKING_NONE, | ||
854 | .order = SOC_MBUS_ORDER_LE, | ||
781 | }, | 855 | }, |
782 | }; | 856 | }; |
783 | 857 | ||
858 | /* This will be corrected as we get more formats */ | ||
859 | static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt) | ||
860 | { | ||
861 | return fmt->packing == SOC_MBUS_PACKING_NONE || | ||
862 | (fmt->bits_per_sample == 8 && | ||
863 | fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || | ||
864 | (fmt->bits_per_sample > 8 && | ||
865 | fmt->packing == SOC_MBUS_PACKING_EXTEND16); | ||
866 | } | ||
867 | |||
784 | static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, | 868 | static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, |
785 | struct soc_camera_format_xlate *xlate) | 869 | struct soc_camera_format_xlate *xlate) |
786 | { | 870 | { |
871 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
787 | struct device *dev = icd->dev.parent; | 872 | struct device *dev = icd->dev.parent; |
788 | int ret, k, n; | 873 | int ret, k, n; |
789 | int formats = 0; | 874 | int formats = 0; |
790 | struct sh_mobile_ceu_cam *cam; | 875 | struct sh_mobile_ceu_cam *cam; |
876 | enum v4l2_mbus_pixelcode code; | ||
877 | const struct soc_mbus_pixelfmt *fmt; | ||
791 | 878 | ||
792 | ret = sh_mobile_ceu_try_bus_param(icd); | 879 | ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); |
880 | if (ret < 0) | ||
881 | /* No more formats */ | ||
882 | return 0; | ||
883 | |||
884 | fmt = soc_mbus_get_fmtdesc(code); | ||
885 | if (!fmt) { | ||
886 | dev_err(icd->dev.parent, | ||
887 | "Invalid format code #%d: %d\n", idx, code); | ||
888 | return -EINVAL; | ||
889 | } | ||
890 | |||
891 | ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); | ||
793 | if (ret < 0) | 892 | if (ret < 0) |
794 | return 0; | 893 | return 0; |
795 | 894 | ||
@@ -807,13 +906,13 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, | |||
807 | if (!idx) | 906 | if (!idx) |
808 | cam->extra_fmt = NULL; | 907 | cam->extra_fmt = NULL; |
809 | 908 | ||
810 | switch (icd->formats[idx].fourcc) { | 909 | switch (code) { |
811 | case V4L2_PIX_FMT_UYVY: | 910 | case V4L2_MBUS_FMT_YUYV8_2X8_BE: |
812 | case V4L2_PIX_FMT_VYUY: | 911 | case V4L2_MBUS_FMT_YVYU8_2X8_BE: |
813 | case V4L2_PIX_FMT_YUYV: | 912 | case V4L2_MBUS_FMT_YUYV8_2X8_LE: |
814 | case V4L2_PIX_FMT_YVYU: | 913 | case V4L2_MBUS_FMT_YVYU8_2X8_LE: |
815 | if (cam->extra_fmt) | 914 | if (cam->extra_fmt) |
816 | goto add_single_format; | 915 | break; |
817 | 916 | ||
818 | /* | 917 | /* |
819 | * Our case is simple so far: for any of the above four camera | 918 | * Our case is simple so far: for any of the above four camera |
@@ -824,32 +923,31 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, | |||
824 | * the host_priv pointer and check whether the format you're | 923 | * the host_priv pointer and check whether the format you're |
825 | * going to add now is already there. | 924 | * going to add now is already there. |
826 | */ | 925 | */ |
827 | cam->extra_fmt = (void *)sh_mobile_ceu_formats; | 926 | cam->extra_fmt = sh_mobile_ceu_formats; |
828 | 927 | ||
829 | n = ARRAY_SIZE(sh_mobile_ceu_formats); | 928 | n = ARRAY_SIZE(sh_mobile_ceu_formats); |
830 | formats += n; | 929 | formats += n; |
831 | for (k = 0; xlate && k < n; k++) { | 930 | for (k = 0; xlate && k < n; k++) { |
832 | xlate->host_fmt = &sh_mobile_ceu_formats[k]; | 931 | xlate->host_fmt = &sh_mobile_ceu_formats[k]; |
833 | xlate->cam_fmt = icd->formats + idx; | 932 | xlate->code = code; |
834 | xlate->buswidth = icd->formats[idx].depth; | ||
835 | xlate++; | 933 | xlate++; |
836 | dev_dbg(dev, "Providing format %s using %s\n", | 934 | dev_dbg(dev, "Providing format %s using code %d\n", |
837 | sh_mobile_ceu_formats[k].name, | 935 | sh_mobile_ceu_formats[k].name, code); |
838 | icd->formats[idx].name); | ||
839 | } | 936 | } |
937 | break; | ||
840 | default: | 938 | default: |
841 | add_single_format: | 939 | if (!sh_mobile_ceu_packing_supported(fmt)) |
842 | /* Generic pass-through */ | 940 | return 0; |
843 | formats++; | 941 | } |
844 | if (xlate) { | 942 | |
845 | xlate->host_fmt = icd->formats + idx; | 943 | /* Generic pass-through */ |
846 | xlate->cam_fmt = icd->formats + idx; | 944 | formats++; |
847 | xlate->buswidth = icd->formats[idx].depth; | 945 | if (xlate) { |
848 | xlate++; | 946 | xlate->host_fmt = fmt; |
849 | dev_dbg(dev, | 947 | xlate->code = code; |
850 | "Providing format %s in pass-through mode\n", | 948 | xlate++; |
851 | icd->formats[idx].name); | 949 | dev_dbg(dev, "Providing format %s in pass-through mode\n", |
852 | } | 950 | xlate->host_fmt->name); |
853 | } | 951 | } |
854 | 952 | ||
855 | return formats; | 953 | return formats; |
@@ -1029,17 +1127,15 @@ static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop, | |||
1029 | static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect, | 1127 | static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect, |
1030 | unsigned int *scale_h, unsigned int *scale_v) | 1128 | unsigned int *scale_h, unsigned int *scale_v) |
1031 | { | 1129 | { |
1032 | struct v4l2_format f; | 1130 | struct v4l2_mbus_framefmt mf; |
1033 | int ret; | 1131 | int ret; |
1034 | 1132 | ||
1035 | f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1133 | ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); |
1036 | |||
1037 | ret = v4l2_subdev_call(sd, video, g_fmt, &f); | ||
1038 | if (ret < 0) | 1134 | if (ret < 0) |
1039 | return ret; | 1135 | return ret; |
1040 | 1136 | ||
1041 | *scale_h = calc_generic_scale(rect->width, f.fmt.pix.width); | 1137 | *scale_h = calc_generic_scale(rect->width, mf.width); |
1042 | *scale_v = calc_generic_scale(rect->height, f.fmt.pix.height); | 1138 | *scale_v = calc_generic_scale(rect->height, mf.height); |
1043 | 1139 | ||
1044 | return 0; | 1140 | return 0; |
1045 | } | 1141 | } |
@@ -1054,32 +1150,29 @@ static int get_camera_subwin(struct soc_camera_device *icd, | |||
1054 | if (!ceu_rect->width) { | 1150 | if (!ceu_rect->width) { |
1055 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1151 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1056 | struct device *dev = icd->dev.parent; | 1152 | struct device *dev = icd->dev.parent; |
1057 | struct v4l2_format f; | 1153 | struct v4l2_mbus_framefmt mf; |
1058 | struct v4l2_pix_format *pix = &f.fmt.pix; | ||
1059 | int ret; | 1154 | int ret; |
1060 | /* First time */ | 1155 | /* First time */ |
1061 | 1156 | ||
1062 | f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1157 | ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); |
1063 | |||
1064 | ret = v4l2_subdev_call(sd, video, g_fmt, &f); | ||
1065 | if (ret < 0) | 1158 | if (ret < 0) |
1066 | return ret; | 1159 | return ret; |
1067 | 1160 | ||
1068 | dev_geo(dev, "camera fmt %ux%u\n", pix->width, pix->height); | 1161 | dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height); |
1069 | 1162 | ||
1070 | if (pix->width > 2560) { | 1163 | if (mf.width > 2560) { |
1071 | ceu_rect->width = 2560; | 1164 | ceu_rect->width = 2560; |
1072 | ceu_rect->left = (pix->width - 2560) / 2; | 1165 | ceu_rect->left = (mf.width - 2560) / 2; |
1073 | } else { | 1166 | } else { |
1074 | ceu_rect->width = pix->width; | 1167 | ceu_rect->width = mf.width; |
1075 | ceu_rect->left = 0; | 1168 | ceu_rect->left = 0; |
1076 | } | 1169 | } |
1077 | 1170 | ||
1078 | if (pix->height > 1920) { | 1171 | if (mf.height > 1920) { |
1079 | ceu_rect->height = 1920; | 1172 | ceu_rect->height = 1920; |
1080 | ceu_rect->top = (pix->height - 1920) / 2; | 1173 | ceu_rect->top = (mf.height - 1920) / 2; |
1081 | } else { | 1174 | } else { |
1082 | ceu_rect->height = pix->height; | 1175 | ceu_rect->height = mf.height; |
1083 | ceu_rect->top = 0; | 1176 | ceu_rect->top = 0; |
1084 | } | 1177 | } |
1085 | 1178 | ||
@@ -1096,13 +1189,12 @@ static int get_camera_subwin(struct soc_camera_device *icd, | |||
1096 | return 0; | 1189 | return 0; |
1097 | } | 1190 | } |
1098 | 1191 | ||
1099 | static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f, | 1192 | static int client_s_fmt(struct soc_camera_device *icd, |
1100 | bool ceu_can_scale) | 1193 | struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) |
1101 | { | 1194 | { |
1102 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1195 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1103 | struct device *dev = icd->dev.parent; | 1196 | struct device *dev = icd->dev.parent; |
1104 | struct v4l2_pix_format *pix = &f->fmt.pix; | 1197 | unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; |
1105 | unsigned int width = pix->width, height = pix->height, tmp_w, tmp_h; | ||
1106 | unsigned int max_width, max_height; | 1198 | unsigned int max_width, max_height; |
1107 | struct v4l2_cropcap cap; | 1199 | struct v4l2_cropcap cap; |
1108 | int ret; | 1200 | int ret; |
@@ -1116,29 +1208,29 @@ static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f, | |||
1116 | max_width = min(cap.bounds.width, 2560); | 1208 | max_width = min(cap.bounds.width, 2560); |
1117 | max_height = min(cap.bounds.height, 1920); | 1209 | max_height = min(cap.bounds.height, 1920); |
1118 | 1210 | ||
1119 | ret = v4l2_subdev_call(sd, video, s_fmt, f); | 1211 | ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); |
1120 | if (ret < 0) | 1212 | if (ret < 0) |
1121 | return ret; | 1213 | return ret; |
1122 | 1214 | ||
1123 | dev_geo(dev, "camera scaled to %ux%u\n", pix->width, pix->height); | 1215 | dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height); |
1124 | 1216 | ||
1125 | if ((width == pix->width && height == pix->height) || !ceu_can_scale) | 1217 | if ((width == mf->width && height == mf->height) || !ceu_can_scale) |
1126 | return 0; | 1218 | return 0; |
1127 | 1219 | ||
1128 | /* Camera set a format, but geometry is not precise, try to improve */ | 1220 | /* Camera set a format, but geometry is not precise, try to improve */ |
1129 | tmp_w = pix->width; | 1221 | tmp_w = mf->width; |
1130 | tmp_h = pix->height; | 1222 | tmp_h = mf->height; |
1131 | 1223 | ||
1132 | /* width <= max_width && height <= max_height - guaranteed by try_fmt */ | 1224 | /* width <= max_width && height <= max_height - guaranteed by try_fmt */ |
1133 | while ((width > tmp_w || height > tmp_h) && | 1225 | while ((width > tmp_w || height > tmp_h) && |
1134 | tmp_w < max_width && tmp_h < max_height) { | 1226 | tmp_w < max_width && tmp_h < max_height) { |
1135 | tmp_w = min(2 * tmp_w, max_width); | 1227 | tmp_w = min(2 * tmp_w, max_width); |
1136 | tmp_h = min(2 * tmp_h, max_height); | 1228 | tmp_h = min(2 * tmp_h, max_height); |
1137 | pix->width = tmp_w; | 1229 | mf->width = tmp_w; |
1138 | pix->height = tmp_h; | 1230 | mf->height = tmp_h; |
1139 | ret = v4l2_subdev_call(sd, video, s_fmt, f); | 1231 | ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); |
1140 | dev_geo(dev, "Camera scaled to %ux%u\n", | 1232 | dev_geo(dev, "Camera scaled to %ux%u\n", |
1141 | pix->width, pix->height); | 1233 | mf->width, mf->height); |
1142 | if (ret < 0) { | 1234 | if (ret < 0) { |
1143 | /* This shouldn't happen */ | 1235 | /* This shouldn't happen */ |
1144 | dev_err(dev, "Client failed to set format: %d\n", ret); | 1236 | dev_err(dev, "Client failed to set format: %d\n", ret); |
@@ -1156,27 +1248,26 @@ static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f, | |||
1156 | */ | 1248 | */ |
1157 | static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect, | 1249 | static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect, |
1158 | struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect, | 1250 | struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect, |
1159 | struct v4l2_format *f, bool ceu_can_scale) | 1251 | struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) |
1160 | { | 1252 | { |
1161 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1253 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1162 | struct sh_mobile_ceu_cam *cam = icd->host_priv; | 1254 | struct sh_mobile_ceu_cam *cam = icd->host_priv; |
1163 | struct device *dev = icd->dev.parent; | 1255 | struct device *dev = icd->dev.parent; |
1164 | struct v4l2_format f_tmp = *f; | 1256 | struct v4l2_mbus_framefmt mf_tmp = *mf; |
1165 | struct v4l2_pix_format *pix_tmp = &f_tmp.fmt.pix; | ||
1166 | unsigned int scale_h, scale_v; | 1257 | unsigned int scale_h, scale_v; |
1167 | int ret; | 1258 | int ret; |
1168 | 1259 | ||
1169 | /* 5. Apply iterative camera S_FMT for camera user window. */ | 1260 | /* 5. Apply iterative camera S_FMT for camera user window. */ |
1170 | ret = client_s_fmt(icd, &f_tmp, ceu_can_scale); | 1261 | ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale); |
1171 | if (ret < 0) | 1262 | if (ret < 0) |
1172 | return ret; | 1263 | return ret; |
1173 | 1264 | ||
1174 | dev_geo(dev, "5: camera scaled to %ux%u\n", | 1265 | dev_geo(dev, "5: camera scaled to %ux%u\n", |
1175 | pix_tmp->width, pix_tmp->height); | 1266 | mf_tmp.width, mf_tmp.height); |
1176 | 1267 | ||
1177 | /* 6. Retrieve camera output window (g_fmt) */ | 1268 | /* 6. Retrieve camera output window (g_fmt) */ |
1178 | 1269 | ||
1179 | /* unneeded - it is already in "f_tmp" */ | 1270 | /* unneeded - it is already in "mf_tmp" */ |
1180 | 1271 | ||
1181 | /* 7. Calculate new camera scales. */ | 1272 | /* 7. Calculate new camera scales. */ |
1182 | ret = get_camera_scales(sd, rect, &scale_h, &scale_v); | 1273 | ret = get_camera_scales(sd, rect, &scale_h, &scale_v); |
@@ -1185,10 +1276,11 @@ static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect, | |||
1185 | 1276 | ||
1186 | dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v); | 1277 | dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v); |
1187 | 1278 | ||
1188 | cam->cam_width = pix_tmp->width; | 1279 | cam->cam_width = mf_tmp.width; |
1189 | cam->cam_height = pix_tmp->height; | 1280 | cam->cam_height = mf_tmp.height; |
1190 | f->fmt.pix.width = pix_tmp->width; | 1281 | mf->width = mf_tmp.width; |
1191 | f->fmt.pix.height = pix_tmp->height; | 1282 | mf->height = mf_tmp.height; |
1283 | mf->colorspace = mf_tmp.colorspace; | ||
1192 | 1284 | ||
1193 | /* | 1285 | /* |
1194 | * 8. Calculate new CEU crop - apply camera scales to previously | 1286 | * 8. Calculate new CEU crop - apply camera scales to previously |
@@ -1252,8 +1344,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, | |||
1252 | struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect; | 1344 | struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect; |
1253 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1345 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1254 | struct device *dev = icd->dev.parent; | 1346 | struct device *dev = icd->dev.parent; |
1255 | struct v4l2_format f; | 1347 | struct v4l2_mbus_framefmt mf; |
1256 | struct v4l2_pix_format *pix = &f.fmt.pix; | ||
1257 | unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v, | 1348 | unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v, |
1258 | out_width, out_height; | 1349 | out_width, out_height; |
1259 | u32 capsr, cflcr; | 1350 | u32 capsr, cflcr; |
@@ -1302,26 +1393,25 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, | |||
1302 | * 5. Using actual input window and calculated combined scales calculate | 1393 | * 5. Using actual input window and calculated combined scales calculate |
1303 | * camera target output window. | 1394 | * camera target output window. |
1304 | */ | 1395 | */ |
1305 | pix->width = scale_down(cam_rect->width, scale_comb_h); | 1396 | mf.width = scale_down(cam_rect->width, scale_comb_h); |
1306 | pix->height = scale_down(cam_rect->height, scale_comb_v); | 1397 | mf.height = scale_down(cam_rect->height, scale_comb_v); |
1307 | 1398 | ||
1308 | dev_geo(dev, "5: camera target %ux%u\n", pix->width, pix->height); | 1399 | dev_geo(dev, "5: camera target %ux%u\n", mf.width, mf.height); |
1309 | 1400 | ||
1310 | /* 6. - 9. */ | 1401 | /* 6. - 9. */ |
1311 | pix->pixelformat = cam->camera_fmt->fourcc; | 1402 | mf.code = cam->code; |
1312 | pix->colorspace = cam->camera_fmt->colorspace; | 1403 | mf.field = pcdev->field; |
1313 | 1404 | ||
1314 | capsr = capture_save_reset(pcdev); | 1405 | capsr = capture_save_reset(pcdev); |
1315 | dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr); | 1406 | dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr); |
1316 | 1407 | ||
1317 | /* Make relative to camera rectangle */ | 1408 | /* Make relative to camera rectangle */ |
1318 | rect->left -= cam_rect->left; | 1409 | rect->left -= cam_rect->left; |
1319 | rect->top -= cam_rect->top; | 1410 | rect->top -= cam_rect->top; |
1320 | 1411 | ||
1321 | f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1412 | ret = client_scale(icd, cam_rect, rect, ceu_rect, &mf, |
1322 | 1413 | pcdev->image_mode && | |
1323 | ret = client_scale(icd, cam_rect, rect, ceu_rect, &f, | 1414 | V4L2_FIELD_NONE == pcdev->field); |
1324 | pcdev->image_mode && !pcdev->is_interlaced); | ||
1325 | 1415 | ||
1326 | dev_geo(dev, "6-9: %d\n", ret); | 1416 | dev_geo(dev, "6-9: %d\n", ret); |
1327 | 1417 | ||
@@ -1368,8 +1458,7 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, | |||
1368 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | 1458 | struct sh_mobile_ceu_dev *pcdev = ici->priv; |
1369 | struct sh_mobile_ceu_cam *cam = icd->host_priv; | 1459 | struct sh_mobile_ceu_cam *cam = icd->host_priv; |
1370 | struct v4l2_pix_format *pix = &f->fmt.pix; | 1460 | struct v4l2_pix_format *pix = &f->fmt.pix; |
1371 | struct v4l2_format cam_f = *f; | 1461 | struct v4l2_mbus_framefmt mf; |
1372 | struct v4l2_pix_format *cam_pix = &cam_f.fmt.pix; | ||
1373 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1462 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1374 | struct device *dev = icd->dev.parent; | 1463 | struct device *dev = icd->dev.parent; |
1375 | __u32 pixfmt = pix->pixelformat; | 1464 | __u32 pixfmt = pix->pixelformat; |
@@ -1379,18 +1468,20 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, | |||
1379 | unsigned int scale_cam_h, scale_cam_v; | 1468 | unsigned int scale_cam_h, scale_cam_v; |
1380 | u16 scale_v, scale_h; | 1469 | u16 scale_v, scale_h; |
1381 | int ret; | 1470 | int ret; |
1382 | bool is_interlaced, image_mode; | 1471 | bool image_mode; |
1472 | enum v4l2_field field; | ||
1383 | 1473 | ||
1384 | switch (pix->field) { | 1474 | switch (pix->field) { |
1385 | case V4L2_FIELD_INTERLACED: | ||
1386 | is_interlaced = true; | ||
1387 | break; | ||
1388 | case V4L2_FIELD_ANY: | ||
1389 | default: | 1475 | default: |
1390 | pix->field = V4L2_FIELD_NONE; | 1476 | pix->field = V4L2_FIELD_NONE; |
1391 | /* fall-through */ | 1477 | /* fall-through */ |
1478 | case V4L2_FIELD_INTERLACED_TB: | ||
1479 | case V4L2_FIELD_INTERLACED_BT: | ||
1392 | case V4L2_FIELD_NONE: | 1480 | case V4L2_FIELD_NONE: |
1393 | is_interlaced = false; | 1481 | field = pix->field; |
1482 | break; | ||
1483 | case V4L2_FIELD_INTERLACED: | ||
1484 | field = V4L2_FIELD_INTERLACED_TB; | ||
1394 | break; | 1485 | break; |
1395 | } | 1486 | } |
1396 | 1487 | ||
@@ -1438,9 +1529,11 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, | |||
1438 | * 4. Calculate camera output window by applying combined scales to real | 1529 | * 4. Calculate camera output window by applying combined scales to real |
1439 | * input window. | 1530 | * input window. |
1440 | */ | 1531 | */ |
1441 | cam_pix->width = scale_down(cam_rect->width, scale_h); | 1532 | mf.width = scale_down(cam_rect->width, scale_h); |
1442 | cam_pix->height = scale_down(cam_rect->height, scale_v); | 1533 | mf.height = scale_down(cam_rect->height, scale_v); |
1443 | cam_pix->pixelformat = xlate->cam_fmt->fourcc; | 1534 | mf.field = pix->field; |
1535 | mf.colorspace = pix->colorspace; | ||
1536 | mf.code = xlate->code; | ||
1444 | 1537 | ||
1445 | switch (pixfmt) { | 1538 | switch (pixfmt) { |
1446 | case V4L2_PIX_FMT_NV12: | 1539 | case V4L2_PIX_FMT_NV12: |
@@ -1453,51 +1546,61 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, | |||
1453 | image_mode = false; | 1546 | image_mode = false; |
1454 | } | 1547 | } |
1455 | 1548 | ||
1456 | dev_geo(dev, "4: camera output %ux%u\n", | 1549 | dev_geo(dev, "4: camera output %ux%u\n", mf.width, mf.height); |
1457 | cam_pix->width, cam_pix->height); | ||
1458 | 1550 | ||
1459 | /* 5. - 9. */ | 1551 | /* 5. - 9. */ |
1460 | ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &cam_f, | 1552 | ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &mf, |
1461 | image_mode && !is_interlaced); | 1553 | image_mode && V4L2_FIELD_NONE == field); |
1462 | 1554 | ||
1463 | dev_geo(dev, "5-9: client scale %d\n", ret); | 1555 | dev_geo(dev, "5-9: client scale %d\n", ret); |
1464 | 1556 | ||
1465 | /* Done with the camera. Now see if we can improve the result */ | 1557 | /* Done with the camera. Now see if we can improve the result */ |
1466 | 1558 | ||
1467 | dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n", | 1559 | dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n", |
1468 | ret, cam_pix->width, cam_pix->height, pix->width, pix->height); | 1560 | ret, mf.width, mf.height, pix->width, pix->height); |
1469 | if (ret < 0) | 1561 | if (ret < 0) |
1470 | return ret; | 1562 | return ret; |
1471 | 1563 | ||
1564 | if (mf.code != xlate->code) | ||
1565 | return -EINVAL; | ||
1566 | |||
1472 | /* 10. Use CEU scaling to scale to the requested user window. */ | 1567 | /* 10. Use CEU scaling to scale to the requested user window. */ |
1473 | 1568 | ||
1474 | /* We cannot scale up */ | 1569 | /* We cannot scale up */ |
1475 | if (pix->width > cam_pix->width) | 1570 | if (pix->width > mf.width) |
1476 | pix->width = cam_pix->width; | 1571 | pix->width = mf.width; |
1477 | if (pix->width > ceu_rect.width) | 1572 | if (pix->width > ceu_rect.width) |
1478 | pix->width = ceu_rect.width; | 1573 | pix->width = ceu_rect.width; |
1479 | 1574 | ||
1480 | if (pix->height > cam_pix->height) | 1575 | if (pix->height > mf.height) |
1481 | pix->height = cam_pix->height; | 1576 | pix->height = mf.height; |
1482 | if (pix->height > ceu_rect.height) | 1577 | if (pix->height > ceu_rect.height) |
1483 | pix->height = ceu_rect.height; | 1578 | pix->height = ceu_rect.height; |
1484 | 1579 | ||
1485 | /* Let's rock: scale pix->{width x height} down to width x height */ | 1580 | pix->colorspace = mf.colorspace; |
1486 | scale_h = calc_scale(ceu_rect.width, &pix->width); | 1581 | |
1487 | scale_v = calc_scale(ceu_rect.height, &pix->height); | 1582 | if (image_mode) { |
1583 | /* Scale pix->{width x height} down to width x height */ | ||
1584 | scale_h = calc_scale(ceu_rect.width, &pix->width); | ||
1585 | scale_v = calc_scale(ceu_rect.height, &pix->height); | ||
1586 | |||
1587 | pcdev->cflcr = scale_h | (scale_v << 16); | ||
1588 | } else { | ||
1589 | pix->width = ceu_rect.width; | ||
1590 | pix->height = ceu_rect.height; | ||
1591 | scale_h = scale_v = 0; | ||
1592 | pcdev->cflcr = 0; | ||
1593 | } | ||
1488 | 1594 | ||
1489 | dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n", | 1595 | dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n", |
1490 | ceu_rect.width, scale_h, pix->width, | 1596 | ceu_rect.width, scale_h, pix->width, |
1491 | ceu_rect.height, scale_v, pix->height); | 1597 | ceu_rect.height, scale_v, pix->height); |
1492 | 1598 | ||
1493 | pcdev->cflcr = scale_h | (scale_v << 16); | 1599 | cam->code = xlate->code; |
1600 | cam->ceu_rect = ceu_rect; | ||
1601 | icd->current_fmt = xlate; | ||
1494 | 1602 | ||
1495 | icd->buswidth = xlate->buswidth; | 1603 | pcdev->field = field; |
1496 | icd->current_fmt = xlate->host_fmt; | ||
1497 | cam->camera_fmt = xlate->cam_fmt; | ||
1498 | cam->ceu_rect = ceu_rect; | ||
1499 | |||
1500 | pcdev->is_interlaced = is_interlaced; | ||
1501 | pcdev->image_mode = image_mode; | 1604 | pcdev->image_mode = image_mode; |
1502 | 1605 | ||
1503 | return 0; | 1606 | return 0; |
@@ -1509,6 +1612,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
1509 | const struct soc_camera_format_xlate *xlate; | 1612 | const struct soc_camera_format_xlate *xlate; |
1510 | struct v4l2_pix_format *pix = &f->fmt.pix; | 1613 | struct v4l2_pix_format *pix = &f->fmt.pix; |
1511 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1614 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1615 | struct v4l2_mbus_framefmt mf; | ||
1512 | __u32 pixfmt = pix->pixelformat; | 1616 | __u32 pixfmt = pix->pixelformat; |
1513 | int width, height; | 1617 | int width, height; |
1514 | int ret; | 1618 | int ret; |
@@ -1527,18 +1631,27 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
1527 | width = pix->width; | 1631 | width = pix->width; |
1528 | height = pix->height; | 1632 | height = pix->height; |
1529 | 1633 | ||
1530 | pix->bytesperline = pix->width * | 1634 | pix->bytesperline = soc_mbus_bytes_per_line(width, xlate->host_fmt); |
1531 | DIV_ROUND_UP(xlate->host_fmt->depth, 8); | 1635 | if (pix->bytesperline < 0) |
1532 | pix->sizeimage = pix->height * pix->bytesperline; | 1636 | return pix->bytesperline; |
1533 | 1637 | pix->sizeimage = height * pix->bytesperline; | |
1534 | pix->pixelformat = xlate->cam_fmt->fourcc; | ||
1535 | 1638 | ||
1536 | /* limit to sensor capabilities */ | 1639 | /* limit to sensor capabilities */ |
1537 | ret = v4l2_subdev_call(sd, video, try_fmt, f); | 1640 | mf.width = pix->width; |
1538 | pix->pixelformat = pixfmt; | 1641 | mf.height = pix->height; |
1642 | mf.field = pix->field; | ||
1643 | mf.code = xlate->code; | ||
1644 | mf.colorspace = pix->colorspace; | ||
1645 | |||
1646 | ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); | ||
1539 | if (ret < 0) | 1647 | if (ret < 0) |
1540 | return ret; | 1648 | return ret; |
1541 | 1649 | ||
1650 | pix->width = mf.width; | ||
1651 | pix->height = mf.height; | ||
1652 | pix->field = mf.field; | ||
1653 | pix->colorspace = mf.colorspace; | ||
1654 | |||
1542 | switch (pixfmt) { | 1655 | switch (pixfmt) { |
1543 | case V4L2_PIX_FMT_NV12: | 1656 | case V4L2_PIX_FMT_NV12: |
1544 | case V4L2_PIX_FMT_NV21: | 1657 | case V4L2_PIX_FMT_NV21: |
@@ -1547,21 +1660,25 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
1547 | /* FIXME: check against rect_max after converting soc-camera */ | 1660 | /* FIXME: check against rect_max after converting soc-camera */ |
1548 | /* We can scale precisely, need a bigger image from camera */ | 1661 | /* We can scale precisely, need a bigger image from camera */ |
1549 | if (pix->width < width || pix->height < height) { | 1662 | if (pix->width < width || pix->height < height) { |
1550 | int tmp_w = pix->width, tmp_h = pix->height; | 1663 | /* |
1551 | pix->width = 2560; | 1664 | * We presume, the sensor behaves sanely, i.e., if |
1552 | pix->height = 1920; | 1665 | * requested a bigger rectangle, it will not return a |
1553 | ret = v4l2_subdev_call(sd, video, try_fmt, f); | 1666 | * smaller one. |
1667 | */ | ||
1668 | mf.width = 2560; | ||
1669 | mf.height = 1920; | ||
1670 | ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); | ||
1554 | if (ret < 0) { | 1671 | if (ret < 0) { |
1555 | /* Shouldn't actually happen... */ | 1672 | /* Shouldn't actually happen... */ |
1556 | dev_err(icd->dev.parent, | 1673 | dev_err(icd->dev.parent, |
1557 | "FIXME: try_fmt() returned %d\n", ret); | 1674 | "FIXME: client try_fmt() = %d\n", ret); |
1558 | pix->width = tmp_w; | 1675 | return ret; |
1559 | pix->height = tmp_h; | ||
1560 | } | 1676 | } |
1561 | } | 1677 | } |
1562 | if (pix->width > width) | 1678 | /* We will scale exactly */ |
1679 | if (mf.width > width) | ||
1563 | pix->width = width; | 1680 | pix->width = width; |
1564 | if (pix->height > height) | 1681 | if (mf.height > height) |
1565 | pix->height = height; | 1682 | pix->height = height; |
1566 | } | 1683 | } |
1567 | 1684 | ||
@@ -1573,10 +1690,12 @@ static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf, | |||
1573 | { | 1690 | { |
1574 | int i; | 1691 | int i; |
1575 | 1692 | ||
1576 | /* This is for locking debugging only. I removed spinlocks and now I | 1693 | /* |
1694 | * This is for locking debugging only. I removed spinlocks and now I | ||
1577 | * check whether .prepare is ever called on a linked buffer, or whether | 1695 | * check whether .prepare is ever called on a linked buffer, or whether |
1578 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now | 1696 | * a dma IRQ can occur for an in-work or unlinked buffer. Until now |
1579 | * it hadn't triggered */ | 1697 | * it hadn't triggered |
1698 | */ | ||
1580 | for (i = 0; i < p->count; i++) { | 1699 | for (i = 0; i < p->count; i++) { |
1581 | struct sh_mobile_ceu_buffer *buf; | 1700 | struct sh_mobile_ceu_buffer *buf; |
1582 | 1701 | ||
@@ -1624,8 +1743,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q, | |||
1624 | &sh_mobile_ceu_videobuf_ops, | 1743 | &sh_mobile_ceu_videobuf_ops, |
1625 | icd->dev.parent, &pcdev->lock, | 1744 | icd->dev.parent, &pcdev->lock, |
1626 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1745 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1627 | pcdev->is_interlaced ? | 1746 | pcdev->field, |
1628 | V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE, | ||
1629 | sizeof(struct sh_mobile_ceu_buffer), | 1747 | sizeof(struct sh_mobile_ceu_buffer), |
1630 | icd); | 1748 | icd); |
1631 | } | 1749 | } |
@@ -1654,7 +1772,7 @@ static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd, | |||
1654 | 1772 | ||
1655 | switch (ctrl->id) { | 1773 | switch (ctrl->id) { |
1656 | case V4L2_CID_SHARPNESS: | 1774 | case V4L2_CID_SHARPNESS: |
1657 | switch (icd->current_fmt->fourcc) { | 1775 | switch (icd->current_fmt->host_fmt->fourcc) { |
1658 | case V4L2_PIX_FMT_NV12: | 1776 | case V4L2_PIX_FMT_NV12: |
1659 | case V4L2_PIX_FMT_NV21: | 1777 | case V4L2_PIX_FMT_NV21: |
1660 | case V4L2_PIX_FMT_NV16: | 1778 | case V4L2_PIX_FMT_NV16: |
@@ -1836,7 +1954,7 @@ static struct platform_driver sh_mobile_ceu_driver = { | |||
1836 | .pm = &sh_mobile_ceu_dev_pm_ops, | 1954 | .pm = &sh_mobile_ceu_dev_pm_ops, |
1837 | }, | 1955 | }, |
1838 | .probe = sh_mobile_ceu_probe, | 1956 | .probe = sh_mobile_ceu_probe, |
1839 | .remove = __exit_p(sh_mobile_ceu_remove), | 1957 | .remove = __devexit_p(sh_mobile_ceu_remove), |
1840 | }; | 1958 | }; |
1841 | 1959 | ||
1842 | static int __init sh_mobile_ceu_init(void) | 1960 | static int __init sh_mobile_ceu_init(void) |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 4a7711c3e74..cbf8087b286 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
@@ -1007,8 +1007,8 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam) | |||
1007 | else if (cam->stream != STREAM_OFF) { | 1007 | else if (cam->stream != STREAM_OFF) { |
1008 | cam->state |= DEV_MISCONFIGURED; | 1008 | cam->state |= DEV_MISCONFIGURED; |
1009 | DBG(1, "URB timeout reached. The camera is misconfigured. " | 1009 | DBG(1, "URB timeout reached. The camera is misconfigured. " |
1010 | "To use it, close and open /dev/video%d again.", | 1010 | "To use it, close and open %s again.", |
1011 | cam->v4ldev->num); | 1011 | video_device_node_name(cam->v4ldev)); |
1012 | return -EIO; | 1012 | return -EIO; |
1013 | } | 1013 | } |
1014 | 1014 | ||
@@ -1734,7 +1734,8 @@ static void sn9c102_release_resources(struct kref *kref) | |||
1734 | 1734 | ||
1735 | cam = container_of(kref, struct sn9c102_device, kref); | 1735 | cam = container_of(kref, struct sn9c102_device, kref); |
1736 | 1736 | ||
1737 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num); | 1737 | DBG(2, "V4L2 device %s deregistered", |
1738 | video_device_node_name(cam->v4ldev)); | ||
1738 | video_set_drvdata(cam->v4ldev, NULL); | 1739 | video_set_drvdata(cam->v4ldev, NULL); |
1739 | video_unregister_device(cam->v4ldev); | 1740 | video_unregister_device(cam->v4ldev); |
1740 | usb_put_dev(cam->usbdev); | 1741 | usb_put_dev(cam->usbdev); |
@@ -1791,8 +1792,8 @@ static int sn9c102_open(struct file *filp) | |||
1791 | } | 1792 | } |
1792 | 1793 | ||
1793 | if (cam->users) { | 1794 | if (cam->users) { |
1794 | DBG(2, "Device /dev/video%d is already in use", | 1795 | DBG(2, "Device %s is already in use", |
1795 | cam->v4ldev->num); | 1796 | video_device_node_name(cam->v4ldev)); |
1796 | DBG(3, "Simultaneous opens are not supported"); | 1797 | DBG(3, "Simultaneous opens are not supported"); |
1797 | /* | 1798 | /* |
1798 | open() must follow the open flags and should block | 1799 | open() must follow the open flags and should block |
@@ -1845,7 +1846,7 @@ static int sn9c102_open(struct file *filp) | |||
1845 | cam->frame_count = 0; | 1846 | cam->frame_count = 0; |
1846 | sn9c102_empty_framequeues(cam); | 1847 | sn9c102_empty_framequeues(cam); |
1847 | 1848 | ||
1848 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num); | 1849 | DBG(3, "Video device %s is open", video_device_node_name(cam->v4ldev)); |
1849 | 1850 | ||
1850 | out: | 1851 | out: |
1851 | mutex_unlock(&cam->open_mutex); | 1852 | mutex_unlock(&cam->open_mutex); |
@@ -1870,7 +1871,7 @@ static int sn9c102_release(struct file *filp) | |||
1870 | cam->users--; | 1871 | cam->users--; |
1871 | wake_up_interruptible_nr(&cam->wait_open, 1); | 1872 | wake_up_interruptible_nr(&cam->wait_open, 1); |
1872 | 1873 | ||
1873 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num); | 1874 | DBG(3, "Video device %s closed", video_device_node_name(cam->v4ldev)); |
1874 | 1875 | ||
1875 | kref_put(&cam->kref, sn9c102_release_resources); | 1876 | kref_put(&cam->kref, sn9c102_release_resources); |
1876 | 1877 | ||
@@ -2433,8 +2434,8 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) | |||
2433 | if (err) { /* atomic, no rollback in ioctl() */ | 2434 | if (err) { /* atomic, no rollback in ioctl() */ |
2434 | cam->state |= DEV_MISCONFIGURED; | 2435 | cam->state |= DEV_MISCONFIGURED; |
2435 | DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " | 2436 | DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " |
2436 | "use the camera, close and open /dev/video%d again.", | 2437 | "use the camera, close and open %s again.", |
2437 | cam->v4ldev->num); | 2438 | video_device_node_name(cam->v4ldev)); |
2438 | return -EIO; | 2439 | return -EIO; |
2439 | } | 2440 | } |
2440 | 2441 | ||
@@ -2446,8 +2447,8 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) | |||
2446 | nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) { | 2447 | nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) { |
2447 | cam->state |= DEV_MISCONFIGURED; | 2448 | cam->state |= DEV_MISCONFIGURED; |
2448 | DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " | 2449 | DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " |
2449 | "use the camera, close and open /dev/video%d again.", | 2450 | "use the camera, close and open %s again.", |
2450 | cam->v4ldev->num); | 2451 | video_device_node_name(cam->v4ldev)); |
2451 | return -ENOMEM; | 2452 | return -ENOMEM; |
2452 | } | 2453 | } |
2453 | 2454 | ||
@@ -2690,8 +2691,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | |||
2690 | if (err) { /* atomic, no rollback in ioctl() */ | 2691 | if (err) { /* atomic, no rollback in ioctl() */ |
2691 | cam->state |= DEV_MISCONFIGURED; | 2692 | cam->state |= DEV_MISCONFIGURED; |
2692 | DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " | 2693 | DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " |
2693 | "use the camera, close and open /dev/video%d again.", | 2694 | "use the camera, close and open %s again.", |
2694 | cam->v4ldev->num); | 2695 | video_device_node_name(cam->v4ldev)); |
2695 | return -EIO; | 2696 | return -EIO; |
2696 | } | 2697 | } |
2697 | 2698 | ||
@@ -2702,8 +2703,8 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | |||
2702 | nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) { | 2703 | nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) { |
2703 | cam->state |= DEV_MISCONFIGURED; | 2704 | cam->state |= DEV_MISCONFIGURED; |
2704 | DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " | 2705 | DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " |
2705 | "use the camera, close and open /dev/video%d again.", | 2706 | "use the camera, close and open %s again.", |
2706 | cam->v4ldev->num); | 2707 | video_device_node_name(cam->v4ldev)); |
2707 | return -ENOMEM; | 2708 | return -ENOMEM; |
2708 | } | 2709 | } |
2709 | 2710 | ||
@@ -2748,9 +2749,9 @@ sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg) | |||
2748 | err += sn9c102_set_compression(cam, &jc); | 2749 | err += sn9c102_set_compression(cam, &jc); |
2749 | if (err) { /* atomic, no rollback in ioctl() */ | 2750 | if (err) { /* atomic, no rollback in ioctl() */ |
2750 | cam->state |= DEV_MISCONFIGURED; | 2751 | cam->state |= DEV_MISCONFIGURED; |
2751 | DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " | 2752 | DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware problems. " |
2752 | "problems. To use the camera, close and open " | 2753 | "To use the camera, close and open %s again.", |
2753 | "/dev/video%d again.", cam->v4ldev->num); | 2754 | video_device_node_name(cam->v4ldev)); |
2754 | return -EIO; | 2755 | return -EIO; |
2755 | } | 2756 | } |
2756 | 2757 | ||
@@ -3328,7 +3329,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3328 | 3329 | ||
3329 | strcpy(cam->v4ldev->name, "SN9C1xx PC Camera"); | 3330 | strcpy(cam->v4ldev->name, "SN9C1xx PC Camera"); |
3330 | cam->v4ldev->fops = &sn9c102_fops; | 3331 | cam->v4ldev->fops = &sn9c102_fops; |
3331 | cam->v4ldev->minor = video_nr[dev_nr]; | ||
3332 | cam->v4ldev->release = video_device_release; | 3332 | cam->v4ldev->release = video_device_release; |
3333 | cam->v4ldev->parent = &udev->dev; | 3333 | cam->v4ldev->parent = &udev->dev; |
3334 | 3334 | ||
@@ -3346,7 +3346,8 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3346 | goto fail; | 3346 | goto fail; |
3347 | } | 3347 | } |
3348 | 3348 | ||
3349 | DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num); | 3349 | DBG(2, "V4L2 device registered as %s", |
3350 | video_device_node_name(cam->v4ldev)); | ||
3350 | 3351 | ||
3351 | video_set_drvdata(cam->v4ldev, cam); | 3352 | video_set_drvdata(cam->v4ldev, cam); |
3352 | cam->module_param.force_munmap = force_munmap[dev_nr]; | 3353 | cam->module_param.force_munmap = force_munmap[dev_nr]; |
@@ -3398,9 +3399,9 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf) | |||
3398 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); | 3399 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); |
3399 | 3400 | ||
3400 | if (cam->users) { | 3401 | if (cam->users) { |
3401 | DBG(2, "Device /dev/video%d is open! Deregistration and " | 3402 | DBG(2, "Device %s is open! Deregistration and memory " |
3402 | "memory deallocation are deferred.", | 3403 | "deallocation are deferred.", |
3403 | cam->v4ldev->num); | 3404 | video_device_node_name(cam->v4ldev)); |
3404 | cam->state |= DEV_MISCONFIGURED; | 3405 | cam->state |= DEV_MISCONFIGURED; |
3405 | sn9c102_stop_transfer(cam); | 3406 | sn9c102_stop_transfer(cam); |
3406 | cam->state |= DEV_DISCONNECTED; | 3407 | cam->state |= DEV_DISCONNECTED; |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 95fdeb23c2c..6b3fbcca774 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <media/v4l2-ioctl.h> | 31 | #include <media/v4l2-ioctl.h> |
32 | #include <media/v4l2-dev.h> | 32 | #include <media/v4l2-dev.h> |
33 | #include <media/videobuf-core.h> | 33 | #include <media/videobuf-core.h> |
34 | #include <media/soc_mediabus.h> | ||
34 | 35 | ||
35 | /* Default to VGA resolution */ | 36 | /* Default to VGA resolution */ |
36 | #define DEFAULT_WIDTH 640 | 37 | #define DEFAULT_WIDTH 640 |
@@ -40,18 +41,6 @@ static LIST_HEAD(hosts); | |||
40 | static LIST_HEAD(devices); | 41 | static LIST_HEAD(devices); |
41 | static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ | 42 | static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ |
42 | 43 | ||
43 | const struct soc_camera_data_format *soc_camera_format_by_fourcc( | ||
44 | struct soc_camera_device *icd, unsigned int fourcc) | ||
45 | { | ||
46 | unsigned int i; | ||
47 | |||
48 | for (i = 0; i < icd->num_formats; i++) | ||
49 | if (icd->formats[i].fourcc == fourcc) | ||
50 | return icd->formats + i; | ||
51 | return NULL; | ||
52 | } | ||
53 | EXPORT_SYMBOL(soc_camera_format_by_fourcc); | ||
54 | |||
55 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( | 44 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( |
56 | struct soc_camera_device *icd, unsigned int fourcc) | 45 | struct soc_camera_device *icd, unsigned int fourcc) |
57 | { | 46 | { |
@@ -207,21 +196,26 @@ static int soc_camera_dqbuf(struct file *file, void *priv, | |||
207 | /* Always entered with .video_lock held */ | 196 | /* Always entered with .video_lock held */ |
208 | static int soc_camera_init_user_formats(struct soc_camera_device *icd) | 197 | static int soc_camera_init_user_formats(struct soc_camera_device *icd) |
209 | { | 198 | { |
199 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
210 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 200 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
211 | int i, fmts = 0, ret; | 201 | int i, fmts = 0, raw_fmts = 0, ret; |
202 | enum v4l2_mbus_pixelcode code; | ||
203 | |||
204 | while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) | ||
205 | raw_fmts++; | ||
212 | 206 | ||
213 | if (!ici->ops->get_formats) | 207 | if (!ici->ops->get_formats) |
214 | /* | 208 | /* |
215 | * Fallback mode - the host will have to serve all | 209 | * Fallback mode - the host will have to serve all |
216 | * sensor-provided formats one-to-one to the user | 210 | * sensor-provided formats one-to-one to the user |
217 | */ | 211 | */ |
218 | fmts = icd->num_formats; | 212 | fmts = raw_fmts; |
219 | else | 213 | else |
220 | /* | 214 | /* |
221 | * First pass - only count formats this host-sensor | 215 | * First pass - only count formats this host-sensor |
222 | * configuration can provide | 216 | * configuration can provide |
223 | */ | 217 | */ |
224 | for (i = 0; i < icd->num_formats; i++) { | 218 | for (i = 0; i < raw_fmts; i++) { |
225 | ret = ici->ops->get_formats(icd, i, NULL); | 219 | ret = ici->ops->get_formats(icd, i, NULL); |
226 | if (ret < 0) | 220 | if (ret < 0) |
227 | return ret; | 221 | return ret; |
@@ -242,11 +236,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) | |||
242 | 236 | ||
243 | /* Second pass - actually fill data formats */ | 237 | /* Second pass - actually fill data formats */ |
244 | fmts = 0; | 238 | fmts = 0; |
245 | for (i = 0; i < icd->num_formats; i++) | 239 | for (i = 0; i < raw_fmts; i++) |
246 | if (!ici->ops->get_formats) { | 240 | if (!ici->ops->get_formats) { |
247 | icd->user_formats[i].host_fmt = icd->formats + i; | 241 | v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code); |
248 | icd->user_formats[i].cam_fmt = icd->formats + i; | 242 | icd->user_formats[i].host_fmt = |
249 | icd->user_formats[i].buswidth = icd->formats[i].depth; | 243 | soc_mbus_get_fmtdesc(code); |
244 | icd->user_formats[i].code = code; | ||
250 | } else { | 245 | } else { |
251 | ret = ici->ops->get_formats(icd, i, | 246 | ret = ici->ops->get_formats(icd, i, |
252 | &icd->user_formats[fmts]); | 247 | &icd->user_formats[fmts]); |
@@ -255,7 +250,7 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) | |||
255 | fmts += ret; | 250 | fmts += ret; |
256 | } | 251 | } |
257 | 252 | ||
258 | icd->current_fmt = icd->user_formats[0].host_fmt; | 253 | icd->current_fmt = &icd->user_formats[0]; |
259 | 254 | ||
260 | return 0; | 255 | return 0; |
261 | 256 | ||
@@ -281,7 +276,7 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd) | |||
281 | #define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ | 276 | #define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ |
282 | ((x) >> 24) & 0xff | 277 | ((x) >> 24) & 0xff |
283 | 278 | ||
284 | /* Called with .vb_lock held */ | 279 | /* Called with .vb_lock held, or from the first open(2), see comment there */ |
285 | static int soc_camera_set_fmt(struct soc_camera_file *icf, | 280 | static int soc_camera_set_fmt(struct soc_camera_file *icf, |
286 | struct v4l2_format *f) | 281 | struct v4l2_format *f) |
287 | { | 282 | { |
@@ -302,7 +297,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf, | |||
302 | if (ret < 0) { | 297 | if (ret < 0) { |
303 | return ret; | 298 | return ret; |
304 | } else if (!icd->current_fmt || | 299 | } else if (!icd->current_fmt || |
305 | icd->current_fmt->fourcc != pix->pixelformat) { | 300 | icd->current_fmt->host_fmt->fourcc != pix->pixelformat) { |
306 | dev_err(&icd->dev, | 301 | dev_err(&icd->dev, |
307 | "Host driver hasn't set up current format correctly!\n"); | 302 | "Host driver hasn't set up current format correctly!\n"); |
308 | return -EINVAL; | 303 | return -EINVAL; |
@@ -310,6 +305,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf, | |||
310 | 305 | ||
311 | icd->user_width = pix->width; | 306 | icd->user_width = pix->width; |
312 | icd->user_height = pix->height; | 307 | icd->user_height = pix->height; |
308 | icd->colorspace = pix->colorspace; | ||
313 | icf->vb_vidq.field = | 309 | icf->vb_vidq.field = |
314 | icd->field = pix->field; | 310 | icd->field = pix->field; |
315 | 311 | ||
@@ -369,8 +365,9 @@ static int soc_camera_open(struct file *file) | |||
369 | .width = icd->user_width, | 365 | .width = icd->user_width, |
370 | .height = icd->user_height, | 366 | .height = icd->user_height, |
371 | .field = icd->field, | 367 | .field = icd->field, |
372 | .pixelformat = icd->current_fmt->fourcc, | 368 | .colorspace = icd->colorspace, |
373 | .colorspace = icd->current_fmt->colorspace, | 369 | .pixelformat = |
370 | icd->current_fmt->host_fmt->fourcc, | ||
374 | }, | 371 | }, |
375 | }; | 372 | }; |
376 | 373 | ||
@@ -390,7 +387,12 @@ static int soc_camera_open(struct file *file) | |||
390 | goto eiciadd; | 387 | goto eiciadd; |
391 | } | 388 | } |
392 | 389 | ||
393 | /* Try to configure with default parameters */ | 390 | /* |
391 | * Try to configure with default parameters. Notice: this is the | ||
392 | * very first open, so, we cannot race against other calls, | ||
393 | * apart from someone else calling open() simultaneously, but | ||
394 | * .video_lock is protecting us against it. | ||
395 | */ | ||
394 | ret = soc_camera_set_fmt(icf, &f); | 396 | ret = soc_camera_set_fmt(icf, &f); |
395 | if (ret < 0) | 397 | if (ret < 0) |
396 | goto esfmt; | 398 | goto esfmt; |
@@ -534,7 +536,7 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, | |||
534 | { | 536 | { |
535 | struct soc_camera_file *icf = file->private_data; | 537 | struct soc_camera_file *icf = file->private_data; |
536 | struct soc_camera_device *icd = icf->icd; | 538 | struct soc_camera_device *icd = icf->icd; |
537 | const struct soc_camera_data_format *format; | 539 | const struct soc_mbus_pixelfmt *format; |
538 | 540 | ||
539 | WARN_ON(priv != file->private_data); | 541 | WARN_ON(priv != file->private_data); |
540 | 542 | ||
@@ -543,7 +545,8 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, | |||
543 | 545 | ||
544 | format = icd->user_formats[f->index].host_fmt; | 546 | format = icd->user_formats[f->index].host_fmt; |
545 | 547 | ||
546 | strlcpy(f->description, format->name, sizeof(f->description)); | 548 | if (format->name) |
549 | strlcpy(f->description, format->name, sizeof(f->description)); | ||
547 | f->pixelformat = format->fourcc; | 550 | f->pixelformat = format->fourcc; |
548 | return 0; | 551 | return 0; |
549 | } | 552 | } |
@@ -560,12 +563,15 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, | |||
560 | pix->width = icd->user_width; | 563 | pix->width = icd->user_width; |
561 | pix->height = icd->user_height; | 564 | pix->height = icd->user_height; |
562 | pix->field = icf->vb_vidq.field; | 565 | pix->field = icf->vb_vidq.field; |
563 | pix->pixelformat = icd->current_fmt->fourcc; | 566 | pix->pixelformat = icd->current_fmt->host_fmt->fourcc; |
564 | pix->bytesperline = pix->width * | 567 | pix->bytesperline = soc_mbus_bytes_per_line(pix->width, |
565 | DIV_ROUND_UP(icd->current_fmt->depth, 8); | 568 | icd->current_fmt->host_fmt); |
569 | pix->colorspace = icd->colorspace; | ||
570 | if (pix->bytesperline < 0) | ||
571 | return pix->bytesperline; | ||
566 | pix->sizeimage = pix->height * pix->bytesperline; | 572 | pix->sizeimage = pix->height * pix->bytesperline; |
567 | dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n", | 573 | dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n", |
568 | icd->current_fmt->fourcc); | 574 | icd->current_fmt->host_fmt->fourcc); |
569 | return 0; | 575 | return 0; |
570 | } | 576 | } |
571 | 577 | ||
@@ -621,8 +627,10 @@ static int soc_camera_streamoff(struct file *file, void *priv, | |||
621 | 627 | ||
622 | mutex_lock(&icd->video_lock); | 628 | mutex_lock(&icd->video_lock); |
623 | 629 | ||
624 | /* This calls buf_release from host driver's videobuf_queue_ops for all | 630 | /* |
625 | * remaining buffers. When the last buffer is freed, stop capture */ | 631 | * This calls buf_release from host driver's videobuf_queue_ops for all |
632 | * remaining buffers. When the last buffer is freed, stop capture | ||
633 | */ | ||
626 | videobuf_streamoff(&icf->vb_vidq); | 634 | videobuf_streamoff(&icf->vb_vidq); |
627 | 635 | ||
628 | v4l2_subdev_call(sd, video, s_stream, 0); | 636 | v4l2_subdev_call(sd, video, s_stream, 0); |
@@ -892,7 +900,7 @@ static int soc_camera_probe(struct device *dev) | |||
892 | struct soc_camera_link *icl = to_soc_camera_link(icd); | 900 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
893 | struct device *control = NULL; | 901 | struct device *control = NULL; |
894 | struct v4l2_subdev *sd; | 902 | struct v4l2_subdev *sd; |
895 | struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE}; | 903 | struct v4l2_mbus_framefmt mf; |
896 | int ret; | 904 | int ret; |
897 | 905 | ||
898 | dev_info(dev, "Probing %s\n", dev_name(dev)); | 906 | dev_info(dev, "Probing %s\n", dev_name(dev)); |
@@ -963,9 +971,11 @@ static int soc_camera_probe(struct device *dev) | |||
963 | 971 | ||
964 | /* Try to improve our guess of a reasonable window format */ | 972 | /* Try to improve our guess of a reasonable window format */ |
965 | sd = soc_camera_to_subdev(icd); | 973 | sd = soc_camera_to_subdev(icd); |
966 | if (!v4l2_subdev_call(sd, video, g_fmt, &f)) { | 974 | if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { |
967 | icd->user_width = f.fmt.pix.width; | 975 | icd->user_width = mf.width; |
968 | icd->user_height = f.fmt.pix.height; | 976 | icd->user_height = mf.height; |
977 | icd->colorspace = mf.colorspace; | ||
978 | icd->field = mf.field; | ||
969 | } | 979 | } |
970 | 980 | ||
971 | /* Do we have to sysfs_remove_link() before device_unregister()? */ | 981 | /* Do we have to sysfs_remove_link() before device_unregister()? */ |
@@ -1004,8 +1014,10 @@ epower: | |||
1004 | return ret; | 1014 | return ret; |
1005 | } | 1015 | } |
1006 | 1016 | ||
1007 | /* This is called on device_unregister, which only means we have to disconnect | 1017 | /* |
1008 | * from the host, but not remove ourselves from the device list */ | 1018 | * This is called on device_unregister, which only means we have to disconnect |
1019 | * from the host, but not remove ourselves from the device list | ||
1020 | */ | ||
1009 | static int soc_camera_remove(struct device *dev) | 1021 | static int soc_camera_remove(struct device *dev) |
1010 | { | 1022 | { |
1011 | struct soc_camera_device *icd = to_soc_camera_dev(dev); | 1023 | struct soc_camera_device *icd = to_soc_camera_dev(dev); |
@@ -1205,8 +1217,10 @@ static int soc_camera_device_register(struct soc_camera_device *icd) | |||
1205 | } | 1217 | } |
1206 | 1218 | ||
1207 | if (num < 0) | 1219 | if (num < 0) |
1208 | /* ok, we have 256 cameras on this host... | 1220 | /* |
1209 | * man, stay reasonable... */ | 1221 | * ok, we have 256 cameras on this host... |
1222 | * man, stay reasonable... | ||
1223 | */ | ||
1210 | return -ENOMEM; | 1224 | return -ENOMEM; |
1211 | 1225 | ||
1212 | icd->devnum = num; | 1226 | icd->devnum = num; |
@@ -1268,7 +1282,6 @@ static int video_dev_create(struct soc_camera_device *icd) | |||
1268 | vdev->fops = &soc_camera_fops; | 1282 | vdev->fops = &soc_camera_fops; |
1269 | vdev->ioctl_ops = &soc_camera_ioctl_ops; | 1283 | vdev->ioctl_ops = &soc_camera_ioctl_ops; |
1270 | vdev->release = video_device_release; | 1284 | vdev->release = video_device_release; |
1271 | vdev->minor = -1; | ||
1272 | vdev->tvnorms = V4L2_STD_UNKNOWN; | 1285 | vdev->tvnorms = V4L2_STD_UNKNOWN; |
1273 | 1286 | ||
1274 | icd->vdev = vdev; | 1287 | icd->vdev = vdev; |
@@ -1291,8 +1304,7 @@ static int soc_camera_video_start(struct soc_camera_device *icd) | |||
1291 | !icd->ops->set_bus_param) | 1304 | !icd->ops->set_bus_param) |
1292 | return -EINVAL; | 1305 | return -EINVAL; |
1293 | 1306 | ||
1294 | ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, | 1307 | ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1); |
1295 | icd->vdev->minor); | ||
1296 | if (ret < 0) { | 1308 | if (ret < 0) { |
1297 | dev_err(&icd->dev, "video_register_device failed: %d\n", ret); | 1309 | dev_err(&icd->dev, "video_register_device failed: %d\n", ret); |
1298 | return ret; | 1310 | return ret; |
@@ -1335,9 +1347,11 @@ escdevreg: | |||
1335 | return ret; | 1347 | return ret; |
1336 | } | 1348 | } |
1337 | 1349 | ||
1338 | /* Only called on rmmod for each platform device, since they are not | 1350 | /* |
1351 | * Only called on rmmod for each platform device, since they are not | ||
1339 | * hot-pluggable. Now we know, that all our users - hosts and devices have | 1352 | * hot-pluggable. Now we know, that all our users - hosts and devices have |
1340 | * been unloaded already */ | 1353 | * been unloaded already |
1354 | */ | ||
1341 | static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) | 1355 | static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) |
1342 | { | 1356 | { |
1343 | struct soc_camera_device *icd = platform_get_drvdata(pdev); | 1357 | struct soc_camera_device *icd = platform_get_drvdata(pdev); |
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index b6a575ce5da..10b003a8be8 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/drivers/media/video/soc_camera_platform.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | struct soc_camera_platform_priv { | 23 | struct soc_camera_platform_priv { |
24 | struct v4l2_subdev subdev; | 24 | struct v4l2_subdev subdev; |
25 | struct soc_camera_data_format format; | ||
26 | }; | 25 | }; |
27 | 26 | ||
28 | static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev) | 27 | static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev) |
@@ -58,36 +57,36 @@ soc_camera_platform_query_bus_param(struct soc_camera_device *icd) | |||
58 | } | 57 | } |
59 | 58 | ||
60 | static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd, | 59 | static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd, |
61 | struct v4l2_format *f) | 60 | struct v4l2_mbus_framefmt *mf) |
62 | { | 61 | { |
63 | struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); | 62 | struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); |
64 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
65 | 63 | ||
66 | pix->width = p->format.width; | 64 | mf->width = p->format.width; |
67 | pix->height = p->format.height; | 65 | mf->height = p->format.height; |
66 | mf->code = p->format.code; | ||
67 | mf->colorspace = p->format.colorspace; | ||
68 | |||
68 | return 0; | 69 | return 0; |
69 | } | 70 | } |
70 | 71 | ||
71 | static void soc_camera_platform_video_probe(struct soc_camera_device *icd, | 72 | static struct v4l2_subdev_core_ops platform_subdev_core_ops; |
72 | struct platform_device *pdev) | 73 | |
74 | static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, int index, | ||
75 | enum v4l2_mbus_pixelcode *code) | ||
73 | { | 76 | { |
74 | struct soc_camera_platform_priv *priv = get_priv(pdev); | 77 | struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); |
75 | struct soc_camera_platform_info *p = pdev->dev.platform_data; | ||
76 | 78 | ||
77 | priv->format.name = p->format_name; | 79 | if (index) |
78 | priv->format.depth = p->format_depth; | 80 | return -EINVAL; |
79 | priv->format.fourcc = p->format.pixelformat; | ||
80 | priv->format.colorspace = p->format.colorspace; | ||
81 | 81 | ||
82 | icd->formats = &priv->format; | 82 | *code = p->format.code; |
83 | icd->num_formats = 1; | 83 | return 0; |
84 | } | 84 | } |
85 | 85 | ||
86 | static struct v4l2_subdev_core_ops platform_subdev_core_ops; | ||
87 | |||
88 | static struct v4l2_subdev_video_ops platform_subdev_video_ops = { | 86 | static struct v4l2_subdev_video_ops platform_subdev_video_ops = { |
89 | .s_stream = soc_camera_platform_s_stream, | 87 | .s_stream = soc_camera_platform_s_stream, |
90 | .try_fmt = soc_camera_platform_try_fmt, | 88 | .try_mbus_fmt = soc_camera_platform_try_fmt, |
89 | .enum_mbus_fmt = soc_camera_platform_enum_fmt, | ||
91 | }; | 90 | }; |
92 | 91 | ||
93 | static struct v4l2_subdev_ops platform_subdev_ops = { | 92 | static struct v4l2_subdev_ops platform_subdev_ops = { |
@@ -128,13 +127,10 @@ static int soc_camera_platform_probe(struct platform_device *pdev) | |||
128 | /* Set the control device reference */ | 127 | /* Set the control device reference */ |
129 | dev_set_drvdata(&icd->dev, &pdev->dev); | 128 | dev_set_drvdata(&icd->dev, &pdev->dev); |
130 | 129 | ||
131 | icd->y_skip_top = 0; | 130 | icd->ops = &soc_camera_platform_ops; |
132 | icd->ops = &soc_camera_platform_ops; | ||
133 | 131 | ||
134 | ici = to_soc_camera_host(icd->dev.parent); | 132 | ici = to_soc_camera_host(icd->dev.parent); |
135 | 133 | ||
136 | soc_camera_platform_video_probe(icd, pdev); | ||
137 | |||
138 | v4l2_subdev_init(&priv->subdev, &platform_subdev_ops); | 134 | v4l2_subdev_init(&priv->subdev, &platform_subdev_ops); |
139 | v4l2_set_subdevdata(&priv->subdev, p); | 135 | v4l2_set_subdevdata(&priv->subdev, p); |
140 | strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE); | 136 | strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE); |
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c new file mode 100644 index 00000000000..f8d5c87dc2a --- /dev/null +++ b/drivers/media/video/soc_mediabus.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * soc-camera media bus helper routines | ||
3 | * | ||
4 | * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | |||
14 | #include <media/v4l2-device.h> | ||
15 | #include <media/v4l2-mediabus.h> | ||
16 | #include <media/soc_mediabus.h> | ||
17 | |||
18 | #define MBUS_IDX(f) (V4L2_MBUS_FMT_ ## f - V4L2_MBUS_FMT_FIXED - 1) | ||
19 | |||
20 | static const struct soc_mbus_pixelfmt mbus_fmt[] = { | ||
21 | [MBUS_IDX(YUYV8_2X8_LE)] = { | ||
22 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
23 | .name = "YUYV", | ||
24 | .bits_per_sample = 8, | ||
25 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
26 | .order = SOC_MBUS_ORDER_LE, | ||
27 | }, [MBUS_IDX(YVYU8_2X8_LE)] = { | ||
28 | .fourcc = V4L2_PIX_FMT_YVYU, | ||
29 | .name = "YVYU", | ||
30 | .bits_per_sample = 8, | ||
31 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
32 | .order = SOC_MBUS_ORDER_LE, | ||
33 | }, [MBUS_IDX(YUYV8_2X8_BE)] = { | ||
34 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
35 | .name = "UYVY", | ||
36 | .bits_per_sample = 8, | ||
37 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
38 | .order = SOC_MBUS_ORDER_LE, | ||
39 | }, [MBUS_IDX(YVYU8_2X8_BE)] = { | ||
40 | .fourcc = V4L2_PIX_FMT_VYUY, | ||
41 | .name = "VYUY", | ||
42 | .bits_per_sample = 8, | ||
43 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
44 | .order = SOC_MBUS_ORDER_LE, | ||
45 | }, [MBUS_IDX(RGB555_2X8_PADHI_LE)] = { | ||
46 | .fourcc = V4L2_PIX_FMT_RGB555, | ||
47 | .name = "RGB555", | ||
48 | .bits_per_sample = 8, | ||
49 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
50 | .order = SOC_MBUS_ORDER_LE, | ||
51 | }, [MBUS_IDX(RGB555_2X8_PADHI_BE)] = { | ||
52 | .fourcc = V4L2_PIX_FMT_RGB555X, | ||
53 | .name = "RGB555X", | ||
54 | .bits_per_sample = 8, | ||
55 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
56 | .order = SOC_MBUS_ORDER_LE, | ||
57 | }, [MBUS_IDX(RGB565_2X8_LE)] = { | ||
58 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
59 | .name = "RGB565", | ||
60 | .bits_per_sample = 8, | ||
61 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
62 | .order = SOC_MBUS_ORDER_LE, | ||
63 | }, [MBUS_IDX(RGB565_2X8_BE)] = { | ||
64 | .fourcc = V4L2_PIX_FMT_RGB565X, | ||
65 | .name = "RGB565X", | ||
66 | .bits_per_sample = 8, | ||
67 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
68 | .order = SOC_MBUS_ORDER_LE, | ||
69 | }, [MBUS_IDX(SBGGR8_1X8)] = { | ||
70 | .fourcc = V4L2_PIX_FMT_SBGGR8, | ||
71 | .name = "Bayer 8 BGGR", | ||
72 | .bits_per_sample = 8, | ||
73 | .packing = SOC_MBUS_PACKING_NONE, | ||
74 | .order = SOC_MBUS_ORDER_LE, | ||
75 | }, [MBUS_IDX(SBGGR10_1X10)] = { | ||
76 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
77 | .name = "Bayer 10 BGGR", | ||
78 | .bits_per_sample = 10, | ||
79 | .packing = SOC_MBUS_PACKING_EXTEND16, | ||
80 | .order = SOC_MBUS_ORDER_LE, | ||
81 | }, [MBUS_IDX(GREY8_1X8)] = { | ||
82 | .fourcc = V4L2_PIX_FMT_GREY, | ||
83 | .name = "Grey", | ||
84 | .bits_per_sample = 8, | ||
85 | .packing = SOC_MBUS_PACKING_NONE, | ||
86 | .order = SOC_MBUS_ORDER_LE, | ||
87 | }, [MBUS_IDX(Y10_1X10)] = { | ||
88 | .fourcc = V4L2_PIX_FMT_Y10, | ||
89 | .name = "Grey 10bit", | ||
90 | .bits_per_sample = 10, | ||
91 | .packing = SOC_MBUS_PACKING_EXTEND16, | ||
92 | .order = SOC_MBUS_ORDER_LE, | ||
93 | }, [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = { | ||
94 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
95 | .name = "Bayer 10 BGGR", | ||
96 | .bits_per_sample = 8, | ||
97 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
98 | .order = SOC_MBUS_ORDER_LE, | ||
99 | }, [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = { | ||
100 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
101 | .name = "Bayer 10 BGGR", | ||
102 | .bits_per_sample = 8, | ||
103 | .packing = SOC_MBUS_PACKING_2X8_PADLO, | ||
104 | .order = SOC_MBUS_ORDER_LE, | ||
105 | }, [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = { | ||
106 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
107 | .name = "Bayer 10 BGGR", | ||
108 | .bits_per_sample = 8, | ||
109 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
110 | .order = SOC_MBUS_ORDER_BE, | ||
111 | }, [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = { | ||
112 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
113 | .name = "Bayer 10 BGGR", | ||
114 | .bits_per_sample = 8, | ||
115 | .packing = SOC_MBUS_PACKING_2X8_PADLO, | ||
116 | .order = SOC_MBUS_ORDER_BE, | ||
117 | }, | ||
118 | }; | ||
119 | |||
120 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) | ||
121 | { | ||
122 | switch (mf->packing) { | ||
123 | case SOC_MBUS_PACKING_NONE: | ||
124 | return width * mf->bits_per_sample / 8; | ||
125 | case SOC_MBUS_PACKING_2X8_PADHI: | ||
126 | case SOC_MBUS_PACKING_2X8_PADLO: | ||
127 | case SOC_MBUS_PACKING_EXTEND16: | ||
128 | return width * 2; | ||
129 | } | ||
130 | return -EINVAL; | ||
131 | } | ||
132 | EXPORT_SYMBOL(soc_mbus_bytes_per_line); | ||
133 | |||
134 | const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( | ||
135 | enum v4l2_mbus_pixelcode code) | ||
136 | { | ||
137 | if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt)) | ||
138 | return NULL; | ||
139 | return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1; | ||
140 | } | ||
141 | EXPORT_SYMBOL(soc_mbus_get_fmtdesc); | ||
142 | |||
143 | static int __init soc_mbus_init(void) | ||
144 | { | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static void __exit soc_mbus_exit(void) | ||
149 | { | ||
150 | } | ||
151 | |||
152 | module_init(soc_mbus_init); | ||
153 | module_exit(soc_mbus_exit); | ||
154 | |||
155 | MODULE_DESCRIPTION("soc-camera media bus interface"); | ||
156 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | ||
157 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 6b41865f42b..f07a0f6b71c 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c | |||
@@ -1307,7 +1307,6 @@ static void stk_v4l_dev_release(struct video_device *vd) | |||
1307 | 1307 | ||
1308 | static struct video_device stk_v4l_data = { | 1308 | static struct video_device stk_v4l_data = { |
1309 | .name = "stkwebcam", | 1309 | .name = "stkwebcam", |
1310 | .minor = -1, | ||
1311 | .tvnorms = V4L2_STD_UNKNOWN, | 1310 | .tvnorms = V4L2_STD_UNKNOWN, |
1312 | .current_norm = V4L2_STD_UNKNOWN, | 1311 | .current_norm = V4L2_STD_UNKNOWN, |
1313 | .fops = &v4l_stk_fops, | 1312 | .fops = &v4l_stk_fops, |
@@ -1327,8 +1326,8 @@ static int stk_register_video_device(struct stk_camera *dev) | |||
1327 | if (err) | 1326 | if (err) |
1328 | STK_ERROR("v4l registration failed\n"); | 1327 | STK_ERROR("v4l registration failed\n"); |
1329 | else | 1328 | else |
1330 | STK_INFO("Syntek USB2.0 Camera is now controlling video device" | 1329 | STK_INFO("Syntek USB2.0 Camera is now controlling device %s\n", |
1331 | " /dev/video%d\n", dev->vdev.num); | 1330 | video_device_node_name(&dev->vdev)); |
1332 | return err; | 1331 | return err; |
1333 | } | 1332 | } |
1334 | 1333 | ||
@@ -1418,8 +1417,8 @@ static void stk_camera_disconnect(struct usb_interface *interface) | |||
1418 | wake_up_interruptible(&dev->wait_frame); | 1417 | wake_up_interruptible(&dev->wait_frame); |
1419 | stk_remove_sysfs_files(&dev->vdev); | 1418 | stk_remove_sysfs_files(&dev->vdev); |
1420 | 1419 | ||
1421 | STK_INFO("Syntek USB2.0 Camera release resources " | 1420 | STK_INFO("Syntek USB2.0 Camera release resources device %s\n", |
1422 | "video device /dev/video%d\n", dev->vdev.num); | 1421 | video_device_node_name(&dev->vdev)); |
1423 | 1422 | ||
1424 | video_unregister_device(&dev->vdev); | 1423 | video_unregister_device(&dev->vdev); |
1425 | } | 1424 | } |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index eaada39c76f..a057824e7eb 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -1921,7 +1921,6 @@ static const struct v4l2_file_operations saa_fops = { | |||
1921 | static struct video_device saa_template = { | 1921 | static struct video_device saa_template = { |
1922 | .name = "SAA7146A", | 1922 | .name = "SAA7146A", |
1923 | .fops = &saa_fops, | 1923 | .fops = &saa_fops, |
1924 | .minor = -1, | ||
1925 | .release = video_device_release_empty, | 1924 | .release = video_device_release_empty, |
1926 | }; | 1925 | }; |
1927 | 1926 | ||
@@ -1972,7 +1971,6 @@ static int __devinit configure_saa7146(struct pci_dev *pdev, int num) | |||
1972 | 1971 | ||
1973 | saa->id = pdev->device; | 1972 | saa->id = pdev->device; |
1974 | saa->irq = pdev->irq; | 1973 | saa->irq = pdev->irq; |
1975 | saa->video_dev.minor = -1; | ||
1976 | saa->saa7146_adr = pci_resource_start(pdev, 0); | 1974 | saa->saa7146_adr = pci_resource_start(pdev, 0); |
1977 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision); | 1975 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision); |
1978 | 1976 | ||
@@ -2134,7 +2132,7 @@ static void stradis_release_saa(struct pci_dev *pdev) | |||
2134 | free_irq(saa->irq, saa); | 2132 | free_irq(saa->irq, saa); |
2135 | if (saa->saa7146_mem) | 2133 | if (saa->saa7146_mem) |
2136 | iounmap(saa->saa7146_mem); | 2134 | iounmap(saa->saa7146_mem); |
2137 | if (saa->video_dev.minor != -1) | 2135 | if (video_is_registered(&saa->video_dev)) |
2138 | video_unregister_device(&saa->video_dev); | 2136 | video_unregister_device(&saa->video_dev); |
2139 | } | 2137 | } |
2140 | 2138 | ||
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index 6a91714125d..5938ad8702e 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c | |||
@@ -1405,7 +1405,6 @@ static struct video_device stv680_template = { | |||
1405 | .name = "STV0680 USB camera", | 1405 | .name = "STV0680 USB camera", |
1406 | .fops = &stv680_fops, | 1406 | .fops = &stv680_fops, |
1407 | .release = video_device_release, | 1407 | .release = video_device_release, |
1408 | .minor = -1, | ||
1409 | }; | 1408 | }; |
1410 | 1409 | ||
1411 | static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id) | 1410 | static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id) |
@@ -1467,8 +1466,8 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id | |||
1467 | retval = -EIO; | 1466 | retval = -EIO; |
1468 | goto error_vdev; | 1467 | goto error_vdev; |
1469 | } | 1468 | } |
1470 | PDEBUG(0, "STV(i): registered new video device: video%d", | 1469 | PDEBUG(0, "STV(i): registered new video device: %s", |
1471 | stv680->vdev->num); | 1470 | video_device_node_name(stv680->vdev)); |
1472 | 1471 | ||
1473 | usb_set_intfdata (intf, stv680); | 1472 | usb_set_intfdata (intf, stv680); |
1474 | retval = stv680_create_sysfs_files(stv680->vdev); | 1473 | retval = stv680_create_sysfs_files(stv680->vdev); |
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 269ab044072..5b801a6e1ee 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <media/tw9910.h> | 29 | #include <media/tw9910.h> |
30 | 30 | ||
31 | #define GET_ID(val) ((val & 0xF8) >> 3) | 31 | #define GET_ID(val) ((val & 0xF8) >> 3) |
32 | #define GET_ReV(val) (val & 0x07) | 32 | #define GET_REV(val) (val & 0x07) |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * register offset | 35 | * register offset |
@@ -117,7 +117,7 @@ | |||
117 | #define LCTL24 0x68 | 117 | #define LCTL24 0x68 |
118 | #define LCTL25 0x69 | 118 | #define LCTL25 0x69 |
119 | #define LCTL26 0x6A | 119 | #define LCTL26 0x6A |
120 | #define HSGEGIN 0x6B | 120 | #define HSBEGIN 0x6B |
121 | #define HSEND 0x6C | 121 | #define HSEND 0x6C |
122 | #define OVSDLY 0x6D | 122 | #define OVSDLY 0x6D |
123 | #define OVSEND 0x6E | 123 | #define OVSEND 0x6E |
@@ -152,7 +152,10 @@ | |||
152 | /* 1 : non-auto */ | 152 | /* 1 : non-auto */ |
153 | #define VSCTL 0x08 /* 1 : Vertical out ctrl by DVALID */ | 153 | #define VSCTL 0x08 /* 1 : Vertical out ctrl by DVALID */ |
154 | /* 0 : Vertical out ctrl by HACTIVE and DVALID */ | 154 | /* 0 : Vertical out ctrl by HACTIVE and DVALID */ |
155 | #define OEN 0x04 /* Output Enable together with TRI_SEL. */ | 155 | #define OEN_TRI_SEL_MASK 0x07 |
156 | #define OEN_TRI_SEL_ALL_ON 0x00 /* Enable output for Rev0/Rev1 */ | ||
157 | #define OEN_TRI_SEL_ALL_OFF_r0 0x06 /* All tri-stated for Rev0 */ | ||
158 | #define OEN_TRI_SEL_ALL_OFF_r1 0x07 /* All tri-stated for Rev1 */ | ||
156 | 159 | ||
157 | /* OUTCTR1 */ | 160 | /* OUTCTR1 */ |
158 | #define VSP_LO 0x00 /* 0 : VS pin output polarity is active low */ | 161 | #define VSP_LO 0x00 /* 0 : VS pin output polarity is active low */ |
@@ -178,11 +181,18 @@ | |||
178 | * but all register content remain unchanged. | 181 | * but all register content remain unchanged. |
179 | * This bit is self-resetting. | 182 | * This bit is self-resetting. |
180 | */ | 183 | */ |
184 | #define ACNTL1_PDN_MASK 0x0e | ||
185 | #define CLK_PDN 0x08 /* system clock power down */ | ||
186 | #define Y_PDN 0x04 /* Luma ADC power down */ | ||
187 | #define C_PDN 0x02 /* Chroma ADC power down */ | ||
188 | |||
189 | /* ACNTL2 */ | ||
190 | #define ACNTL2_PDN_MASK 0x40 | ||
191 | #define PLL_PDN 0x40 /* PLL power down */ | ||
181 | 192 | ||
182 | /* VBICNTL */ | 193 | /* VBICNTL */ |
183 | /* RTSEL : control the real time signal | 194 | |
184 | * output from the MPOUT pin | 195 | /* RTSEL : control the real time signal output from the MPOUT pin */ |
185 | */ | ||
186 | #define RTSEL_MASK 0x07 | 196 | #define RTSEL_MASK 0x07 |
187 | #define RTSEL_VLOSS 0x00 /* 0000 = Video loss */ | 197 | #define RTSEL_VLOSS 0x00 /* 0000 = Video loss */ |
188 | #define RTSEL_HLOCK 0x01 /* 0001 = H-lock */ | 198 | #define RTSEL_HLOCK 0x01 /* 0001 = H-lock */ |
@@ -226,28 +236,7 @@ struct tw9910_priv { | |||
226 | struct v4l2_subdev subdev; | 236 | struct v4l2_subdev subdev; |
227 | struct tw9910_video_info *info; | 237 | struct tw9910_video_info *info; |
228 | const struct tw9910_scale_ctrl *scale; | 238 | const struct tw9910_scale_ctrl *scale; |
229 | }; | 239 | u32 revision; |
230 | |||
231 | /* | ||
232 | * register settings | ||
233 | */ | ||
234 | |||
235 | #define ENDMARKER { 0xff, 0xff } | ||
236 | |||
237 | static const struct regval_list tw9910_default_regs[] = | ||
238 | { | ||
239 | { OPFORM, 0x00 }, | ||
240 | { OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC }, | ||
241 | ENDMARKER, | ||
242 | }; | ||
243 | |||
244 | static const struct soc_camera_data_format tw9910_color_fmt[] = { | ||
245 | { | ||
246 | .name = "VYUY", | ||
247 | .fourcc = V4L2_PIX_FMT_VYUY, | ||
248 | .depth = 16, | ||
249 | .colorspace = V4L2_COLORSPACE_SMPTE170M, | ||
250 | } | ||
251 | }; | 240 | }; |
252 | 241 | ||
253 | static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = { | 242 | static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = { |
@@ -340,13 +329,6 @@ static const struct tw9910_scale_ctrl tw9910_pal_scales[] = { | |||
340 | }, | 329 | }, |
341 | }; | 330 | }; |
342 | 331 | ||
343 | static const struct tw9910_cropping_ctrl tw9910_cropping_ctrl = { | ||
344 | .vdelay = 0x0012, | ||
345 | .vactive = 0x00F0, | ||
346 | .hdelay = 0x0010, | ||
347 | .hactive = 0x02D0, | ||
348 | }; | ||
349 | |||
350 | static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = { | 332 | static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = { |
351 | .start = 0x0260, | 333 | .start = 0x0260, |
352 | .end = 0x0300, | 334 | .end = 0x0300, |
@@ -361,6 +343,19 @@ static struct tw9910_priv *to_tw9910(const struct i2c_client *client) | |||
361 | subdev); | 343 | subdev); |
362 | } | 344 | } |
363 | 345 | ||
346 | static int tw9910_mask_set(struct i2c_client *client, u8 command, | ||
347 | u8 mask, u8 set) | ||
348 | { | ||
349 | s32 val = i2c_smbus_read_byte_data(client, command); | ||
350 | if (val < 0) | ||
351 | return val; | ||
352 | |||
353 | val &= ~mask; | ||
354 | val |= set & mask; | ||
355 | |||
356 | return i2c_smbus_write_byte_data(client, command, val); | ||
357 | } | ||
358 | |||
364 | static int tw9910_set_scale(struct i2c_client *client, | 359 | static int tw9910_set_scale(struct i2c_client *client, |
365 | const struct tw9910_scale_ctrl *scale) | 360 | const struct tw9910_scale_ctrl *scale) |
366 | { | 361 | { |
@@ -383,47 +378,14 @@ static int tw9910_set_scale(struct i2c_client *client, | |||
383 | return ret; | 378 | return ret; |
384 | } | 379 | } |
385 | 380 | ||
386 | static int tw9910_set_cropping(struct i2c_client *client, | ||
387 | const struct tw9910_cropping_ctrl *cropping) | ||
388 | { | ||
389 | int ret; | ||
390 | |||
391 | ret = i2c_smbus_write_byte_data(client, CROP_HI, | ||
392 | (cropping->vdelay & 0x0300) >> 2 | | ||
393 | (cropping->vactive & 0x0300) >> 4 | | ||
394 | (cropping->hdelay & 0x0300) >> 6 | | ||
395 | (cropping->hactive & 0x0300) >> 8); | ||
396 | if (ret < 0) | ||
397 | return ret; | ||
398 | |||
399 | ret = i2c_smbus_write_byte_data(client, VDELAY_LO, | ||
400 | cropping->vdelay & 0x00FF); | ||
401 | if (ret < 0) | ||
402 | return ret; | ||
403 | |||
404 | ret = i2c_smbus_write_byte_data(client, VACTIVE_LO, | ||
405 | cropping->vactive & 0x00FF); | ||
406 | if (ret < 0) | ||
407 | return ret; | ||
408 | |||
409 | ret = i2c_smbus_write_byte_data(client, HDELAY_LO, | ||
410 | cropping->hdelay & 0x00FF); | ||
411 | if (ret < 0) | ||
412 | return ret; | ||
413 | |||
414 | ret = i2c_smbus_write_byte_data(client, HACTIVE_LO, | ||
415 | cropping->hactive & 0x00FF); | ||
416 | |||
417 | return ret; | ||
418 | } | ||
419 | |||
420 | static int tw9910_set_hsync(struct i2c_client *client, | 381 | static int tw9910_set_hsync(struct i2c_client *client, |
421 | const struct tw9910_hsync_ctrl *hsync) | 382 | const struct tw9910_hsync_ctrl *hsync) |
422 | { | 383 | { |
384 | struct tw9910_priv *priv = to_tw9910(client); | ||
423 | int ret; | 385 | int ret; |
424 | 386 | ||
425 | /* bit 10 - 3 */ | 387 | /* bit 10 - 3 */ |
426 | ret = i2c_smbus_write_byte_data(client, HSGEGIN, | 388 | ret = i2c_smbus_write_byte_data(client, HSBEGIN, |
427 | (hsync->start & 0x07F8) >> 3); | 389 | (hsync->start & 0x07F8) >> 3); |
428 | if (ret < 0) | 390 | if (ret < 0) |
429 | return ret; | 391 | return ret; |
@@ -434,50 +396,41 @@ static int tw9910_set_hsync(struct i2c_client *client, | |||
434 | if (ret < 0) | 396 | if (ret < 0) |
435 | return ret; | 397 | return ret; |
436 | 398 | ||
399 | /* So far only revisions 0 and 1 have been seen */ | ||
437 | /* bit 2 - 0 */ | 400 | /* bit 2 - 0 */ |
438 | ret = i2c_smbus_read_byte_data(client, HSLOWCTL); | 401 | if (1 == priv->revision) |
439 | if (ret < 0) | 402 | ret = tw9910_mask_set(client, HSLOWCTL, 0x77, |
440 | return ret; | 403 | (hsync->start & 0x0007) << 4 | |
441 | 404 | (hsync->end & 0x0007)); | |
442 | ret = i2c_smbus_write_byte_data(client, HSLOWCTL, | ||
443 | (ret & 0x88) | | ||
444 | (hsync->start & 0x0007) << 4 | | ||
445 | (hsync->end & 0x0007)); | ||
446 | 405 | ||
447 | return ret; | 406 | return ret; |
448 | } | 407 | } |
449 | 408 | ||
450 | static int tw9910_write_array(struct i2c_client *client, | 409 | static void tw9910_reset(struct i2c_client *client) |
451 | const struct regval_list *vals) | ||
452 | { | 410 | { |
453 | while (vals->reg_num != 0xff) { | 411 | tw9910_mask_set(client, ACNTL1, SRESET, SRESET); |
454 | int ret = i2c_smbus_write_byte_data(client, | 412 | msleep(1); |
455 | vals->reg_num, | ||
456 | vals->value); | ||
457 | if (ret < 0) | ||
458 | return ret; | ||
459 | vals++; | ||
460 | } | ||
461 | return 0; | ||
462 | } | 413 | } |
463 | 414 | ||
464 | static int tw9910_mask_set(struct i2c_client *client, u8 command, | 415 | static int tw9910_power(struct i2c_client *client, int enable) |
465 | u8 mask, u8 set) | ||
466 | { | 416 | { |
467 | s32 val = i2c_smbus_read_byte_data(client, command); | 417 | int ret; |
468 | if (val < 0) | 418 | u8 acntl1; |
469 | return val; | 419 | u8 acntl2; |
470 | 420 | ||
471 | val &= ~mask; | 421 | if (enable) { |
472 | val |= set & mask; | 422 | acntl1 = 0; |
423 | acntl2 = 0; | ||
424 | } else { | ||
425 | acntl1 = CLK_PDN | Y_PDN | C_PDN; | ||
426 | acntl2 = PLL_PDN; | ||
427 | } | ||
473 | 428 | ||
474 | return i2c_smbus_write_byte_data(client, command, val); | 429 | ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1); |
475 | } | 430 | if (ret < 0) |
431 | return ret; | ||
476 | 432 | ||
477 | static void tw9910_reset(struct i2c_client *client) | 433 | return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2); |
478 | { | ||
479 | i2c_smbus_write_byte_data(client, ACNTL1, SRESET); | ||
480 | msleep(1); | ||
481 | } | 434 | } |
482 | 435 | ||
483 | static const struct tw9910_scale_ctrl* | 436 | static const struct tw9910_scale_ctrl* |
@@ -518,27 +471,62 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) | |||
518 | { | 471 | { |
519 | struct i2c_client *client = sd->priv; | 472 | struct i2c_client *client = sd->priv; |
520 | struct tw9910_priv *priv = to_tw9910(client); | 473 | struct tw9910_priv *priv = to_tw9910(client); |
474 | u8 val; | ||
475 | int ret; | ||
521 | 476 | ||
522 | if (!enable) | 477 | if (!enable) { |
523 | return 0; | 478 | switch (priv->revision) { |
479 | case 0: | ||
480 | val = OEN_TRI_SEL_ALL_OFF_r0; | ||
481 | break; | ||
482 | case 1: | ||
483 | val = OEN_TRI_SEL_ALL_OFF_r1; | ||
484 | break; | ||
485 | default: | ||
486 | dev_err(&client->dev, "un-supported revision\n"); | ||
487 | return -EINVAL; | ||
488 | } | ||
489 | } else { | ||
490 | val = OEN_TRI_SEL_ALL_ON; | ||
524 | 491 | ||
525 | if (!priv->scale) { | 492 | if (!priv->scale) { |
526 | dev_err(&client->dev, "norm select error\n"); | 493 | dev_err(&client->dev, "norm select error\n"); |
527 | return -EPERM; | 494 | return -EPERM; |
495 | } | ||
496 | |||
497 | dev_dbg(&client->dev, "%s %dx%d\n", | ||
498 | priv->scale->name, | ||
499 | priv->scale->width, | ||
500 | priv->scale->height); | ||
528 | } | 501 | } |
529 | 502 | ||
530 | dev_dbg(&client->dev, "%s %dx%d\n", | 503 | ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val); |
531 | priv->scale->name, | 504 | if (ret < 0) |
532 | priv->scale->width, | 505 | return ret; |
533 | priv->scale->height); | ||
534 | 506 | ||
535 | return 0; | 507 | return tw9910_power(client, enable); |
536 | } | 508 | } |
537 | 509 | ||
538 | static int tw9910_set_bus_param(struct soc_camera_device *icd, | 510 | static int tw9910_set_bus_param(struct soc_camera_device *icd, |
539 | unsigned long flags) | 511 | unsigned long flags) |
540 | { | 512 | { |
541 | return 0; | 513 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
514 | struct i2c_client *client = sd->priv; | ||
515 | u8 val = VSSL_VVALID | HSSL_DVALID; | ||
516 | |||
517 | /* | ||
518 | * set OUTCTR1 | ||
519 | * | ||
520 | * We use VVALID and DVALID signals to control VSYNC and HSYNC | ||
521 | * outputs, in this mode their polarity is inverted. | ||
522 | */ | ||
523 | if (flags & SOCAM_HSYNC_ACTIVE_LOW) | ||
524 | val |= HSP_HI; | ||
525 | |||
526 | if (flags & SOCAM_VSYNC_ACTIVE_LOW) | ||
527 | val |= VSP_HI; | ||
528 | |||
529 | return i2c_smbus_write_byte_data(client, OUTCTR1, val); | ||
542 | } | 530 | } |
543 | 531 | ||
544 | static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) | 532 | static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) |
@@ -548,6 +536,7 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) | |||
548 | struct soc_camera_link *icl = to_soc_camera_link(icd); | 536 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
549 | unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | | 537 | unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | |
550 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | | 538 | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | |
539 | SOCAM_VSYNC_ACTIVE_LOW | SOCAM_HSYNC_ACTIVE_LOW | | ||
551 | SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; | 540 | SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; |
552 | 541 | ||
553 | return soc_camera_apply_sensor_flags(icl, flags); | 542 | return soc_camera_apply_sensor_flags(icl, flags); |
@@ -576,8 +565,11 @@ static int tw9910_enum_input(struct soc_camera_device *icd, | |||
576 | static int tw9910_g_chip_ident(struct v4l2_subdev *sd, | 565 | static int tw9910_g_chip_ident(struct v4l2_subdev *sd, |
577 | struct v4l2_dbg_chip_ident *id) | 566 | struct v4l2_dbg_chip_ident *id) |
578 | { | 567 | { |
568 | struct i2c_client *client = sd->priv; | ||
569 | struct tw9910_priv *priv = to_tw9910(client); | ||
570 | |||
579 | id->ident = V4L2_IDENT_TW9910; | 571 | id->ident = V4L2_IDENT_TW9910; |
580 | id->revision = 0; | 572 | id->revision = priv->revision; |
581 | 573 | ||
582 | return 0; | 574 | return 0; |
583 | } | 575 | } |
@@ -596,7 +588,8 @@ static int tw9910_g_register(struct v4l2_subdev *sd, | |||
596 | if (ret < 0) | 588 | if (ret < 0) |
597 | return ret; | 589 | return ret; |
598 | 590 | ||
599 | /* ret = int | 591 | /* |
592 | * ret = int | ||
600 | * reg->val = __u64 | 593 | * reg->val = __u64 |
601 | */ | 594 | */ |
602 | reg->val = (__u64)ret; | 595 | reg->val = (__u64)ret; |
@@ -637,9 +630,6 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
637 | * reset hardware | 630 | * reset hardware |
638 | */ | 631 | */ |
639 | tw9910_reset(client); | 632 | tw9910_reset(client); |
640 | ret = tw9910_write_array(client, tw9910_default_regs); | ||
641 | if (ret < 0) | ||
642 | goto tw9910_set_fmt_error; | ||
643 | 633 | ||
644 | /* | 634 | /* |
645 | * set bus width | 635 | * set bus width |
@@ -688,13 +678,6 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
688 | goto tw9910_set_fmt_error; | 678 | goto tw9910_set_fmt_error; |
689 | 679 | ||
690 | /* | 680 | /* |
691 | * set cropping | ||
692 | */ | ||
693 | ret = tw9910_set_cropping(client, &tw9910_cropping_ctrl); | ||
694 | if (ret < 0) | ||
695 | goto tw9910_set_fmt_error; | ||
696 | |||
697 | /* | ||
698 | * set hsync | 681 | * set hsync |
699 | */ | 682 | */ |
700 | ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl); | 683 | ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl); |
@@ -762,11 +745,11 @@ static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
762 | return 0; | 745 | return 0; |
763 | } | 746 | } |
764 | 747 | ||
765 | static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 748 | static int tw9910_g_fmt(struct v4l2_subdev *sd, |
749 | struct v4l2_mbus_framefmt *mf) | ||
766 | { | 750 | { |
767 | struct i2c_client *client = sd->priv; | 751 | struct i2c_client *client = sd->priv; |
768 | struct tw9910_priv *priv = to_tw9910(client); | 752 | struct tw9910_priv *priv = to_tw9910(client); |
769 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
770 | 753 | ||
771 | if (!priv->scale) { | 754 | if (!priv->scale) { |
772 | int ret; | 755 | int ret; |
@@ -783,74 +766,76 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |||
783 | return ret; | 766 | return ret; |
784 | } | 767 | } |
785 | 768 | ||
786 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 769 | mf->width = priv->scale->width; |
787 | 770 | mf->height = priv->scale->height; | |
788 | pix->width = priv->scale->width; | 771 | mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE; |
789 | pix->height = priv->scale->height; | 772 | mf->colorspace = V4L2_COLORSPACE_JPEG; |
790 | pix->pixelformat = V4L2_PIX_FMT_VYUY; | 773 | mf->field = V4L2_FIELD_INTERLACED_BT; |
791 | pix->colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
792 | pix->field = V4L2_FIELD_INTERLACED; | ||
793 | 774 | ||
794 | return 0; | 775 | return 0; |
795 | } | 776 | } |
796 | 777 | ||
797 | static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 778 | static int tw9910_s_fmt(struct v4l2_subdev *sd, |
779 | struct v4l2_mbus_framefmt *mf) | ||
798 | { | 780 | { |
799 | struct i2c_client *client = sd->priv; | 781 | struct i2c_client *client = sd->priv; |
800 | struct tw9910_priv *priv = to_tw9910(client); | 782 | struct tw9910_priv *priv = to_tw9910(client); |
801 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
802 | /* See tw9910_s_crop() - no proper cropping support */ | 783 | /* See tw9910_s_crop() - no proper cropping support */ |
803 | struct v4l2_crop a = { | 784 | struct v4l2_crop a = { |
804 | .c = { | 785 | .c = { |
805 | .left = 0, | 786 | .left = 0, |
806 | .top = 0, | 787 | .top = 0, |
807 | .width = pix->width, | 788 | .width = mf->width, |
808 | .height = pix->height, | 789 | .height = mf->height, |
809 | }, | 790 | }, |
810 | }; | 791 | }; |
811 | int i, ret; | 792 | int ret; |
793 | |||
794 | WARN_ON(mf->field != V4L2_FIELD_ANY && | ||
795 | mf->field != V4L2_FIELD_INTERLACED_BT); | ||
812 | 796 | ||
813 | /* | 797 | /* |
814 | * check color format | 798 | * check color format |
815 | */ | 799 | */ |
816 | for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++) | 800 | if (mf->code != V4L2_MBUS_FMT_YUYV8_2X8_BE) |
817 | if (pix->pixelformat == tw9910_color_fmt[i].fourcc) | ||
818 | break; | ||
819 | |||
820 | if (i == ARRAY_SIZE(tw9910_color_fmt)) | ||
821 | return -EINVAL; | 801 | return -EINVAL; |
822 | 802 | ||
803 | mf->colorspace = V4L2_COLORSPACE_JPEG; | ||
804 | |||
823 | ret = tw9910_s_crop(sd, &a); | 805 | ret = tw9910_s_crop(sd, &a); |
824 | if (!ret) { | 806 | if (!ret) { |
825 | pix->width = priv->scale->width; | 807 | mf->width = priv->scale->width; |
826 | pix->height = priv->scale->height; | 808 | mf->height = priv->scale->height; |
827 | } | 809 | } |
828 | return ret; | 810 | return ret; |
829 | } | 811 | } |
830 | 812 | ||
831 | static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 813 | static int tw9910_try_fmt(struct v4l2_subdev *sd, |
814 | struct v4l2_mbus_framefmt *mf) | ||
832 | { | 815 | { |
833 | struct i2c_client *client = sd->priv; | 816 | struct i2c_client *client = sd->priv; |
834 | struct soc_camera_device *icd = client->dev.platform_data; | 817 | struct soc_camera_device *icd = client->dev.platform_data; |
835 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
836 | const struct tw9910_scale_ctrl *scale; | 818 | const struct tw9910_scale_ctrl *scale; |
837 | 819 | ||
838 | if (V4L2_FIELD_ANY == pix->field) { | 820 | if (V4L2_FIELD_ANY == mf->field) { |
839 | pix->field = V4L2_FIELD_INTERLACED; | 821 | mf->field = V4L2_FIELD_INTERLACED_BT; |
840 | } else if (V4L2_FIELD_INTERLACED != pix->field) { | 822 | } else if (V4L2_FIELD_INTERLACED_BT != mf->field) { |
841 | dev_err(&client->dev, "Field type invalid.\n"); | 823 | dev_err(&client->dev, "Field type %d invalid.\n", mf->field); |
842 | return -EINVAL; | 824 | return -EINVAL; |
843 | } | 825 | } |
844 | 826 | ||
827 | mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE; | ||
828 | mf->colorspace = V4L2_COLORSPACE_JPEG; | ||
829 | |||
845 | /* | 830 | /* |
846 | * select suitable norm | 831 | * select suitable norm |
847 | */ | 832 | */ |
848 | scale = tw9910_select_norm(icd, pix->width, pix->height); | 833 | scale = tw9910_select_norm(icd, mf->width, mf->height); |
849 | if (!scale) | 834 | if (!scale) |
850 | return -EINVAL; | 835 | return -EINVAL; |
851 | 836 | ||
852 | pix->width = scale->width; | 837 | mf->width = scale->width; |
853 | pix->height = scale->height; | 838 | mf->height = scale->height; |
854 | 839 | ||
855 | return 0; | 840 | return 0; |
856 | } | 841 | } |
@@ -859,7 +844,7 @@ static int tw9910_video_probe(struct soc_camera_device *icd, | |||
859 | struct i2c_client *client) | 844 | struct i2c_client *client) |
860 | { | 845 | { |
861 | struct tw9910_priv *priv = to_tw9910(client); | 846 | struct tw9910_priv *priv = to_tw9910(client); |
862 | s32 val; | 847 | s32 id; |
863 | 848 | ||
864 | /* | 849 | /* |
865 | * We must have a parent by now. And it cannot be a wrong one. | 850 | * We must have a parent by now. And it cannot be a wrong one. |
@@ -878,23 +863,24 @@ static int tw9910_video_probe(struct soc_camera_device *icd, | |||
878 | return -ENODEV; | 863 | return -ENODEV; |
879 | } | 864 | } |
880 | 865 | ||
881 | icd->formats = tw9910_color_fmt; | ||
882 | icd->num_formats = ARRAY_SIZE(tw9910_color_fmt); | ||
883 | |||
884 | /* | 866 | /* |
885 | * check and show Product ID | 867 | * check and show Product ID |
868 | * So far only revisions 0 and 1 have been seen | ||
886 | */ | 869 | */ |
887 | val = i2c_smbus_read_byte_data(client, ID); | 870 | id = i2c_smbus_read_byte_data(client, ID); |
871 | priv->revision = GET_REV(id); | ||
872 | id = GET_ID(id); | ||
888 | 873 | ||
889 | if (0x0B != GET_ID(val) || | 874 | if (0x0B != id || |
890 | 0x00 != GET_ReV(val)) { | 875 | 0x01 < priv->revision) { |
891 | dev_err(&client->dev, | 876 | dev_err(&client->dev, |
892 | "Product ID error %x:%x\n", GET_ID(val), GET_ReV(val)); | 877 | "Product ID error %x:%x\n", |
878 | id, priv->revision); | ||
893 | return -ENODEV; | 879 | return -ENODEV; |
894 | } | 880 | } |
895 | 881 | ||
896 | dev_info(&client->dev, | 882 | dev_info(&client->dev, |
897 | "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val)); | 883 | "tw9910 Product ID %0x:%0x\n", id, priv->revision); |
898 | 884 | ||
899 | icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; | 885 | icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; |
900 | icd->vdev->current_norm = V4L2_STD_NTSC; | 886 | icd->vdev->current_norm = V4L2_STD_NTSC; |
@@ -917,14 +903,25 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { | |||
917 | #endif | 903 | #endif |
918 | }; | 904 | }; |
919 | 905 | ||
906 | static int tw9910_enum_fmt(struct v4l2_subdev *sd, int index, | ||
907 | enum v4l2_mbus_pixelcode *code) | ||
908 | { | ||
909 | if (index) | ||
910 | return -EINVAL; | ||
911 | |||
912 | *code = V4L2_MBUS_FMT_YUYV8_2X8_BE; | ||
913 | return 0; | ||
914 | } | ||
915 | |||
920 | static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { | 916 | static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { |
921 | .s_stream = tw9910_s_stream, | 917 | .s_stream = tw9910_s_stream, |
922 | .g_fmt = tw9910_g_fmt, | 918 | .g_mbus_fmt = tw9910_g_fmt, |
923 | .s_fmt = tw9910_s_fmt, | 919 | .s_mbus_fmt = tw9910_s_fmt, |
924 | .try_fmt = tw9910_try_fmt, | 920 | .try_mbus_fmt = tw9910_try_fmt, |
925 | .cropcap = tw9910_cropcap, | 921 | .cropcap = tw9910_cropcap, |
926 | .g_crop = tw9910_g_crop, | 922 | .g_crop = tw9910_g_crop, |
927 | .s_crop = tw9910_s_crop, | 923 | .s_crop = tw9910_s_crop, |
924 | .enum_mbus_fmt = tw9910_enum_fmt, | ||
928 | }; | 925 | }; |
929 | 926 | ||
930 | static struct v4l2_subdev_ops tw9910_subdev_ops = { | 927 | static struct v4l2_subdev_ops tw9910_subdev_ops = { |
@@ -954,10 +951,10 @@ static int tw9910_probe(struct i2c_client *client, | |||
954 | } | 951 | } |
955 | 952 | ||
956 | icl = to_soc_camera_link(icd); | 953 | icl = to_soc_camera_link(icd); |
957 | if (!icl) | 954 | if (!icl || !icl->priv) |
958 | return -EINVAL; | 955 | return -EINVAL; |
959 | 956 | ||
960 | info = container_of(icl, struct tw9910_video_info, link); | 957 | info = icl->priv; |
961 | 958 | ||
962 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 959 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
963 | dev_err(&client->dev, | 960 | dev_err(&client->dev, |
@@ -975,7 +972,7 @@ static int tw9910_probe(struct i2c_client *client, | |||
975 | v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); | 972 | v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); |
976 | 973 | ||
977 | icd->ops = &tw9910_ops; | 974 | icd->ops = &tw9910_ops; |
978 | icd->iface = info->link.bus_id; | 975 | icd->iface = icl->bus_id; |
979 | 976 | ||
980 | ret = tw9910_video_probe(icd, client); | 977 | ret = tw9910_video_probe(icd, client); |
981 | if (ret) { | 978 | if (ret) { |
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c index dea8b321fb4..5ac37c6c431 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/media/video/usbvideo/usbvideo.c | |||
@@ -1053,9 +1053,9 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) | |||
1053 | "%s: video_register_device() successful\n", __func__); | 1053 | "%s: video_register_device() successful\n", __func__); |
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | dev_info(&uvd->dev->dev, "%s on /dev/video%d: canvas=%s videosize=%s\n", | 1056 | dev_info(&uvd->dev->dev, "%s on %s: canvas=%s videosize=%s\n", |
1057 | (uvd->handle != NULL) ? uvd->handle->drvName : "???", | 1057 | (uvd->handle != NULL) ? uvd->handle->drvName : "???", |
1058 | uvd->vdev.num, tmp2, tmp1); | 1058 | video_device_node_name(&uvd->vdev), tmp2, tmp1); |
1059 | 1059 | ||
1060 | usb_get_dev(uvd->dev); | 1060 | usb_get_dev(uvd->dev); |
1061 | return 0; | 1061 | return 0; |
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 45fce39ec9a..6030410c667 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c | |||
@@ -796,7 +796,6 @@ static const struct v4l2_file_operations vicam_fops = { | |||
796 | static struct video_device vicam_template = { | 796 | static struct video_device vicam_template = { |
797 | .name = "ViCam-based USB Camera", | 797 | .name = "ViCam-based USB Camera", |
798 | .fops = &vicam_fops, | 798 | .fops = &vicam_fops, |
799 | .minor = -1, | ||
800 | .release = video_device_release_empty, | 799 | .release = video_device_release_empty, |
801 | }; | 800 | }; |
802 | 801 | ||
@@ -873,8 +872,8 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) | |||
873 | return -EIO; | 872 | return -EIO; |
874 | } | 873 | } |
875 | 874 | ||
876 | printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n", | 875 | printk(KERN_INFO "ViCam webcam driver now controlling device %s\n", |
877 | cam->vdev.num); | 876 | video_device_node_name(&cam->vdev)); |
878 | 877 | ||
879 | usb_set_intfdata (intf, cam); | 878 | usb_set_intfdata (intf, cam); |
880 | 879 | ||
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index c19f51dba2e..0613922997e 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c | |||
@@ -215,8 +215,8 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) | |||
215 | memcpy(&usbvision->i2c_adap, &i2c_adap_template, | 215 | memcpy(&usbvision->i2c_adap, &i2c_adap_template, |
216 | sizeof(struct i2c_adapter)); | 216 | sizeof(struct i2c_adapter)); |
217 | 217 | ||
218 | sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name), | 218 | sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name, |
219 | " #%d", usbvision->vdev->num); | 219 | usbvision->dev->bus->busnum, usbvision->dev->devpath); |
220 | PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name); | 220 | PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name); |
221 | usbvision->i2c_adap.dev.parent = &usbvision->dev->dev; | 221 | usbvision->i2c_adap.dev.parent = &usbvision->dev->dev; |
222 | 222 | ||
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index c07b0ac452a..1054546db90 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -1328,7 +1328,6 @@ static struct video_device usbvision_video_template = { | |||
1328 | .ioctl_ops = &usbvision_ioctl_ops, | 1328 | .ioctl_ops = &usbvision_ioctl_ops, |
1329 | .name = "usbvision-video", | 1329 | .name = "usbvision-video", |
1330 | .release = video_device_release, | 1330 | .release = video_device_release, |
1331 | .minor = -1, | ||
1332 | .tvnorms = USBVISION_NORMS, | 1331 | .tvnorms = USBVISION_NORMS, |
1333 | .current_norm = V4L2_STD_PAL | 1332 | .current_norm = V4L2_STD_PAL |
1334 | }; | 1333 | }; |
@@ -1362,7 +1361,6 @@ static struct video_device usbvision_radio_template = { | |||
1362 | .fops = &usbvision_radio_fops, | 1361 | .fops = &usbvision_radio_fops, |
1363 | .name = "usbvision-radio", | 1362 | .name = "usbvision-radio", |
1364 | .release = video_device_release, | 1363 | .release = video_device_release, |
1365 | .minor = -1, | ||
1366 | .ioctl_ops = &usbvision_radio_ioctl_ops, | 1364 | .ioctl_ops = &usbvision_radio_ioctl_ops, |
1367 | 1365 | ||
1368 | .tvnorms = USBVISION_NORMS, | 1366 | .tvnorms = USBVISION_NORMS, |
@@ -1382,7 +1380,6 @@ static struct video_device usbvision_vbi_template= | |||
1382 | .fops = &usbvision_vbi_fops, | 1380 | .fops = &usbvision_vbi_fops, |
1383 | .release = video_device_release, | 1381 | .release = video_device_release, |
1384 | .name = "usbvision-vbi", | 1382 | .name = "usbvision-vbi", |
1385 | .minor = -1, | ||
1386 | }; | 1383 | }; |
1387 | 1384 | ||
1388 | 1385 | ||
@@ -1404,7 +1401,6 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, | |||
1404 | return NULL; | 1401 | return NULL; |
1405 | } | 1402 | } |
1406 | *vdev = *vdev_template; | 1403 | *vdev = *vdev_template; |
1407 | // vdev->minor = -1; | ||
1408 | vdev->v4l2_dev = &usbvision->v4l2_dev; | 1404 | vdev->v4l2_dev = &usbvision->v4l2_dev; |
1409 | snprintf(vdev->name, sizeof(vdev->name), "%s", name); | 1405 | snprintf(vdev->name, sizeof(vdev->name), "%s", name); |
1410 | video_set_drvdata(vdev, usbvision); | 1406 | video_set_drvdata(vdev, usbvision); |
@@ -1416,9 +1412,9 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) | |||
1416 | { | 1412 | { |
1417 | // vbi Device: | 1413 | // vbi Device: |
1418 | if (usbvision->vbi) { | 1414 | if (usbvision->vbi) { |
1419 | PDEBUG(DBG_PROBE, "unregister /dev/vbi%d [v4l2]", | 1415 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", |
1420 | usbvision->vbi->num); | 1416 | video_device_node_name(usbvision->vbi)); |
1421 | if (usbvision->vbi->minor != -1) { | 1417 | if (video_is_registered(usbvision->vbi)) { |
1422 | video_unregister_device(usbvision->vbi); | 1418 | video_unregister_device(usbvision->vbi); |
1423 | } else { | 1419 | } else { |
1424 | video_device_release(usbvision->vbi); | 1420 | video_device_release(usbvision->vbi); |
@@ -1428,9 +1424,9 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) | |||
1428 | 1424 | ||
1429 | // Radio Device: | 1425 | // Radio Device: |
1430 | if (usbvision->rdev) { | 1426 | if (usbvision->rdev) { |
1431 | PDEBUG(DBG_PROBE, "unregister /dev/radio%d [v4l2]", | 1427 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", |
1432 | usbvision->rdev->num); | 1428 | video_device_node_name(usbvision->rdev)); |
1433 | if (usbvision->rdev->minor != -1) { | 1429 | if (video_is_registered(usbvision->rdev)) { |
1434 | video_unregister_device(usbvision->rdev); | 1430 | video_unregister_device(usbvision->rdev); |
1435 | } else { | 1431 | } else { |
1436 | video_device_release(usbvision->rdev); | 1432 | video_device_release(usbvision->rdev); |
@@ -1440,9 +1436,9 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) | |||
1440 | 1436 | ||
1441 | // Video Device: | 1437 | // Video Device: |
1442 | if (usbvision->vdev) { | 1438 | if (usbvision->vdev) { |
1443 | PDEBUG(DBG_PROBE, "unregister /dev/video%d [v4l2]", | 1439 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", |
1444 | usbvision->vdev->num); | 1440 | video_device_node_name(usbvision->vdev)); |
1445 | if (usbvision->vdev->minor != -1) { | 1441 | if (video_is_registered(usbvision->vdev)) { |
1446 | video_unregister_device(usbvision->vdev); | 1442 | video_unregister_device(usbvision->vdev); |
1447 | } else { | 1443 | } else { |
1448 | video_device_release(usbvision->vdev); | 1444 | video_device_release(usbvision->vdev); |
@@ -1466,8 +1462,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) | |||
1466 | video_nr)<0) { | 1462 | video_nr)<0) { |
1467 | goto err_exit; | 1463 | goto err_exit; |
1468 | } | 1464 | } |
1469 | printk(KERN_INFO "USBVision[%d]: registered USBVision Video device /dev/video%d [v4l2]\n", | 1465 | printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n", |
1470 | usbvision->nr, usbvision->vdev->num); | 1466 | usbvision->nr, video_device_node_name(usbvision->vdev)); |
1471 | 1467 | ||
1472 | // Radio Device: | 1468 | // Radio Device: |
1473 | if (usbvision_device_data[usbvision->DevModel].Radio) { | 1469 | if (usbvision_device_data[usbvision->DevModel].Radio) { |
@@ -1483,8 +1479,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) | |||
1483 | radio_nr)<0) { | 1479 | radio_nr)<0) { |
1484 | goto err_exit; | 1480 | goto err_exit; |
1485 | } | 1481 | } |
1486 | printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device /dev/radio%d [v4l2]\n", | 1482 | printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n", |
1487 | usbvision->nr, usbvision->rdev->num); | 1483 | usbvision->nr, video_device_node_name(usbvision->rdev)); |
1488 | } | 1484 | } |
1489 | // vbi Device: | 1485 | // vbi Device: |
1490 | if (usbvision_device_data[usbvision->DevModel].vbi) { | 1486 | if (usbvision_device_data[usbvision->DevModel].vbi) { |
@@ -1499,8 +1495,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) | |||
1499 | vbi_nr)<0) { | 1495 | vbi_nr)<0) { |
1500 | goto err_exit; | 1496 | goto err_exit; |
1501 | } | 1497 | } |
1502 | printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device /dev/vbi%d [v4l2] (Not Working Yet!)\n", | 1498 | printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device %s [v4l2] (Not Working Yet!)\n", |
1503 | usbvision->nr, usbvision->vbi->num); | 1499 | usbvision->nr, video_device_node_name(usbvision->vbi)); |
1504 | } | 1500 | } |
1505 | // all done | 1501 | // all done |
1506 | return 0; | 1502 | return 0; |
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index c31bc50113b..391cccca7ff 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -1651,7 +1651,6 @@ static int uvc_register_video(struct uvc_device *dev, | |||
1651 | * get another one. | 1651 | * get another one. |
1652 | */ | 1652 | */ |
1653 | vdev->parent = &dev->intf->dev; | 1653 | vdev->parent = &dev->intf->dev; |
1654 | vdev->minor = -1; | ||
1655 | vdev->fops = &uvc_fops; | 1654 | vdev->fops = &uvc_fops; |
1656 | vdev->release = uvc_release; | 1655 | vdev->release = uvc_release; |
1657 | strlcpy(vdev->name, dev->name, sizeof vdev->name); | 1656 | strlcpy(vdev->name, dev->name, sizeof vdev->name); |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 05139a4f14f..9a9802830d4 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -145,7 +145,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream, | |||
145 | uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non " | 145 | uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non " |
146 | "compliance - GET_MIN/MAX(PROBE) incorrectly " | 146 | "compliance - GET_MIN/MAX(PROBE) incorrectly " |
147 | "supported. Enabling workaround.\n"); | 147 | "supported. Enabling workaround.\n"); |
148 | memset(ctrl, 0, sizeof ctrl); | 148 | memset(ctrl, 0, sizeof *ctrl); |
149 | ctrl->wCompQuality = le16_to_cpup((__le16 *)data); | 149 | ctrl->wCompQuality = le16_to_cpup((__le16 *)data); |
150 | ret = 0; | 150 | ret = 0; |
151 | goto out; | 151 | goto out; |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index e8e5affbabc..36b5cb86fb5 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -1024,3 +1024,50 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, | |||
1024 | } | 1024 | } |
1025 | } | 1025 | } |
1026 | EXPORT_SYMBOL_GPL(v4l_bound_align_image); | 1026 | EXPORT_SYMBOL_GPL(v4l_bound_align_image); |
1027 | |||
1028 | /** | ||
1029 | * v4l_fill_dv_preset_info - fill description of a digital video preset | ||
1030 | * @preset - preset value | ||
1031 | * @info - pointer to struct v4l2_dv_enum_preset | ||
1032 | * | ||
1033 | * drivers can use this helper function to fill description of dv preset | ||
1034 | * in info. | ||
1035 | */ | ||
1036 | int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info) | ||
1037 | { | ||
1038 | static const struct v4l2_dv_preset_info { | ||
1039 | u16 width; | ||
1040 | u16 height; | ||
1041 | const char *name; | ||
1042 | } dv_presets[] = { | ||
1043 | { 0, 0, "Invalid" }, /* V4L2_DV_INVALID */ | ||
1044 | { 720, 480, "480p@59.94" }, /* V4L2_DV_480P59_94 */ | ||
1045 | { 720, 576, "576p@50" }, /* V4L2_DV_576P50 */ | ||
1046 | { 1280, 720, "720p@24" }, /* V4L2_DV_720P24 */ | ||
1047 | { 1280, 720, "720p@25" }, /* V4L2_DV_720P25 */ | ||
1048 | { 1280, 720, "720p@30" }, /* V4L2_DV_720P30 */ | ||
1049 | { 1280, 720, "720p@50" }, /* V4L2_DV_720P50 */ | ||
1050 | { 1280, 720, "720p@59.94" }, /* V4L2_DV_720P59_94 */ | ||
1051 | { 1280, 720, "720p@60" }, /* V4L2_DV_720P60 */ | ||
1052 | { 1920, 1080, "1080i@29.97" }, /* V4L2_DV_1080I29_97 */ | ||
1053 | { 1920, 1080, "1080i@30" }, /* V4L2_DV_1080I30 */ | ||
1054 | { 1920, 1080, "1080i@25" }, /* V4L2_DV_1080I25 */ | ||
1055 | { 1920, 1080, "1080i@50" }, /* V4L2_DV_1080I50 */ | ||
1056 | { 1920, 1080, "1080i@60" }, /* V4L2_DV_1080I60 */ | ||
1057 | { 1920, 1080, "1080p@24" }, /* V4L2_DV_1080P24 */ | ||
1058 | { 1920, 1080, "1080p@25" }, /* V4L2_DV_1080P25 */ | ||
1059 | { 1920, 1080, "1080p@30" }, /* V4L2_DV_1080P30 */ | ||
1060 | { 1920, 1080, "1080p@50" }, /* V4L2_DV_1080P50 */ | ||
1061 | { 1920, 1080, "1080p@60" }, /* V4L2_DV_1080P60 */ | ||
1062 | }; | ||
1063 | |||
1064 | if (info == NULL || preset >= ARRAY_SIZE(dv_presets)) | ||
1065 | return -EINVAL; | ||
1066 | |||
1067 | info->preset = preset; | ||
1068 | info->width = dv_presets[preset].width; | ||
1069 | info->height = dv_presets[preset].height; | ||
1070 | strlcpy(info->name, dv_presets[preset].name, sizeof(info->name)); | ||
1071 | return 0; | ||
1072 | } | ||
1073 | EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info); | ||
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index 997975d5e02..c4150bd2633 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c | |||
@@ -1077,6 +1077,12 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
1077 | case VIDIOC_DBG_G_REGISTER: | 1077 | case VIDIOC_DBG_G_REGISTER: |
1078 | case VIDIOC_DBG_G_CHIP_IDENT: | 1078 | case VIDIOC_DBG_G_CHIP_IDENT: |
1079 | case VIDIOC_S_HW_FREQ_SEEK: | 1079 | case VIDIOC_S_HW_FREQ_SEEK: |
1080 | case VIDIOC_ENUM_DV_PRESETS: | ||
1081 | case VIDIOC_S_DV_PRESET: | ||
1082 | case VIDIOC_G_DV_PRESET: | ||
1083 | case VIDIOC_QUERY_DV_PRESET: | ||
1084 | case VIDIOC_S_DV_TIMINGS: | ||
1085 | case VIDIOC_G_DV_TIMINGS: | ||
1080 | ret = do_video_ioctl(file, cmd, arg); | 1086 | ret = do_video_ioctl(file, cmd, arg); |
1081 | break; | 1087 | break; |
1082 | 1088 | ||
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 500cbe9891a..70906991606 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -189,7 +189,7 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, | |||
189 | 189 | ||
190 | if (!vdev->fops->read) | 190 | if (!vdev->fops->read) |
191 | return -EINVAL; | 191 | return -EINVAL; |
192 | if (video_is_unregistered(vdev)) | 192 | if (!video_is_registered(vdev)) |
193 | return -EIO; | 193 | return -EIO; |
194 | return vdev->fops->read(filp, buf, sz, off); | 194 | return vdev->fops->read(filp, buf, sz, off); |
195 | } | 195 | } |
@@ -201,7 +201,7 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
201 | 201 | ||
202 | if (!vdev->fops->write) | 202 | if (!vdev->fops->write) |
203 | return -EINVAL; | 203 | return -EINVAL; |
204 | if (video_is_unregistered(vdev)) | 204 | if (!video_is_registered(vdev)) |
205 | return -EIO; | 205 | return -EIO; |
206 | return vdev->fops->write(filp, buf, sz, off); | 206 | return vdev->fops->write(filp, buf, sz, off); |
207 | } | 207 | } |
@@ -210,7 +210,7 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | |||
210 | { | 210 | { |
211 | struct video_device *vdev = video_devdata(filp); | 211 | struct video_device *vdev = video_devdata(filp); |
212 | 212 | ||
213 | if (!vdev->fops->poll || video_is_unregistered(vdev)) | 213 | if (!vdev->fops->poll || !video_is_registered(vdev)) |
214 | return DEFAULT_POLLMASK; | 214 | return DEFAULT_POLLMASK; |
215 | return vdev->fops->poll(filp, poll); | 215 | return vdev->fops->poll(filp, poll); |
216 | } | 216 | } |
@@ -250,7 +250,7 @@ static unsigned long v4l2_get_unmapped_area(struct file *filp, | |||
250 | 250 | ||
251 | if (!vdev->fops->get_unmapped_area) | 251 | if (!vdev->fops->get_unmapped_area) |
252 | return -ENOSYS; | 252 | return -ENOSYS; |
253 | if (video_is_unregistered(vdev)) | 253 | if (!video_is_registered(vdev)) |
254 | return -ENODEV; | 254 | return -ENODEV; |
255 | return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags); | 255 | return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags); |
256 | } | 256 | } |
@@ -260,8 +260,7 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
260 | { | 260 | { |
261 | struct video_device *vdev = video_devdata(filp); | 261 | struct video_device *vdev = video_devdata(filp); |
262 | 262 | ||
263 | if (!vdev->fops->mmap || | 263 | if (!vdev->fops->mmap || !video_is_registered(vdev)) |
264 | video_is_unregistered(vdev)) | ||
265 | return -ENODEV; | 264 | return -ENODEV; |
266 | return vdev->fops->mmap(filp, vm); | 265 | return vdev->fops->mmap(filp, vm); |
267 | } | 266 | } |
@@ -277,7 +276,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
277 | vdev = video_devdata(filp); | 276 | vdev = video_devdata(filp); |
278 | /* return ENODEV if the video device has been removed | 277 | /* return ENODEV if the video device has been removed |
279 | already or if it is not registered anymore. */ | 278 | already or if it is not registered anymore. */ |
280 | if (vdev == NULL || video_is_unregistered(vdev)) { | 279 | if (vdev == NULL || !video_is_registered(vdev)) { |
281 | mutex_unlock(&videodev_lock); | 280 | mutex_unlock(&videodev_lock); |
282 | return -ENODEV; | 281 | return -ENODEV; |
283 | } | 282 | } |
@@ -551,10 +550,11 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, | |||
551 | vdev->dev.release = v4l2_device_release; | 550 | vdev->dev.release = v4l2_device_release; |
552 | 551 | ||
553 | if (nr != -1 && nr != vdev->num && warn_if_nr_in_use) | 552 | if (nr != -1 && nr != vdev->num && warn_if_nr_in_use) |
554 | printk(KERN_WARNING "%s: requested %s%d, got %s%d\n", | 553 | printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__, |
555 | __func__, name_base, nr, name_base, vdev->num); | 554 | name_base, nr, video_device_node_name(vdev)); |
556 | 555 | ||
557 | /* Part 5: Activate this minor. The char device can now be used. */ | 556 | /* Part 5: Activate this minor. The char device can now be used. */ |
557 | set_bit(V4L2_FL_REGISTERED, &vdev->flags); | ||
558 | mutex_lock(&videodev_lock); | 558 | mutex_lock(&videodev_lock); |
559 | video_device[vdev->minor] = vdev; | 559 | video_device[vdev->minor] = vdev; |
560 | mutex_unlock(&videodev_lock); | 560 | mutex_unlock(&videodev_lock); |
@@ -593,11 +593,11 @@ EXPORT_SYMBOL(video_register_device_no_warn); | |||
593 | void video_unregister_device(struct video_device *vdev) | 593 | void video_unregister_device(struct video_device *vdev) |
594 | { | 594 | { |
595 | /* Check if vdev was ever registered at all */ | 595 | /* Check if vdev was ever registered at all */ |
596 | if (!vdev || vdev->minor < 0) | 596 | if (!vdev || !video_is_registered(vdev)) |
597 | return; | 597 | return; |
598 | 598 | ||
599 | mutex_lock(&videodev_lock); | 599 | mutex_lock(&videodev_lock); |
600 | set_bit(V4L2_FL_UNREGISTERED, &vdev->flags); | 600 | clear_bit(V4L2_FL_REGISTERED, &vdev->flags); |
601 | mutex_unlock(&videodev_lock); | 601 | mutex_unlock(&videodev_lock); |
602 | device_unregister(&vdev->dev); | 602 | device_unregister(&vdev->dev); |
603 | } | 603 | } |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 30cc3347ae5..4b11257c318 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -284,6 +284,12 @@ static const char *v4l2_ioctls[] = { | |||
284 | [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", | 284 | [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", |
285 | [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", | 285 | [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", |
286 | #endif | 286 | #endif |
287 | [_IOC_NR(VIDIOC_ENUM_DV_PRESETS)] = "VIDIOC_ENUM_DV_PRESETS", | ||
288 | [_IOC_NR(VIDIOC_S_DV_PRESET)] = "VIDIOC_S_DV_PRESET", | ||
289 | [_IOC_NR(VIDIOC_G_DV_PRESET)] = "VIDIOC_G_DV_PRESET", | ||
290 | [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET", | ||
291 | [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS", | ||
292 | [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS", | ||
287 | }; | 293 | }; |
288 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 294 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
289 | 295 | ||
@@ -1135,6 +1141,19 @@ static long __video_do_ioctl(struct file *file, | |||
1135 | { | 1141 | { |
1136 | struct v4l2_input *p = arg; | 1142 | struct v4l2_input *p = arg; |
1137 | 1143 | ||
1144 | /* | ||
1145 | * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & | ||
1146 | * CAP_STD here based on ioctl handler provided by the | ||
1147 | * driver. If the driver doesn't support these | ||
1148 | * for a specific input, it must override these flags. | ||
1149 | */ | ||
1150 | if (ops->vidioc_s_std) | ||
1151 | p->capabilities |= V4L2_IN_CAP_STD; | ||
1152 | if (ops->vidioc_s_dv_preset) | ||
1153 | p->capabilities |= V4L2_IN_CAP_PRESETS; | ||
1154 | if (ops->vidioc_s_dv_timings) | ||
1155 | p->capabilities |= V4L2_IN_CAP_CUSTOM_TIMINGS; | ||
1156 | |||
1138 | if (!ops->vidioc_enum_input) | 1157 | if (!ops->vidioc_enum_input) |
1139 | break; | 1158 | break; |
1140 | 1159 | ||
@@ -1179,6 +1198,19 @@ static long __video_do_ioctl(struct file *file, | |||
1179 | if (!ops->vidioc_enum_output) | 1198 | if (!ops->vidioc_enum_output) |
1180 | break; | 1199 | break; |
1181 | 1200 | ||
1201 | /* | ||
1202 | * We set the flags for CAP_PRESETS, CAP_CUSTOM_TIMINGS & | ||
1203 | * CAP_STD here based on ioctl handler provided by the | ||
1204 | * driver. If the driver doesn't support these | ||
1205 | * for a specific output, it must override these flags. | ||
1206 | */ | ||
1207 | if (ops->vidioc_s_std) | ||
1208 | p->capabilities |= V4L2_OUT_CAP_STD; | ||
1209 | if (ops->vidioc_s_dv_preset) | ||
1210 | p->capabilities |= V4L2_OUT_CAP_PRESETS; | ||
1211 | if (ops->vidioc_s_dv_timings) | ||
1212 | p->capabilities |= V4L2_OUT_CAP_CUSTOM_TIMINGS; | ||
1213 | |||
1182 | ret = ops->vidioc_enum_output(file, fh, p); | 1214 | ret = ops->vidioc_enum_output(file, fh, p); |
1183 | if (!ret) | 1215 | if (!ret) |
1184 | dbgarg(cmd, "index=%d, name=%s, type=%d, " | 1216 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
@@ -1794,6 +1826,121 @@ static long __video_do_ioctl(struct file *file, | |||
1794 | } | 1826 | } |
1795 | break; | 1827 | break; |
1796 | } | 1828 | } |
1829 | case VIDIOC_ENUM_DV_PRESETS: | ||
1830 | { | ||
1831 | struct v4l2_dv_enum_preset *p = arg; | ||
1832 | |||
1833 | if (!ops->vidioc_enum_dv_presets) | ||
1834 | break; | ||
1835 | |||
1836 | ret = ops->vidioc_enum_dv_presets(file, fh, p); | ||
1837 | if (!ret) | ||
1838 | dbgarg(cmd, | ||
1839 | "index=%d, preset=%d, name=%s, width=%d," | ||
1840 | " height=%d ", | ||
1841 | p->index, p->preset, p->name, p->width, | ||
1842 | p->height); | ||
1843 | break; | ||
1844 | } | ||
1845 | case VIDIOC_S_DV_PRESET: | ||
1846 | { | ||
1847 | struct v4l2_dv_preset *p = arg; | ||
1848 | |||
1849 | if (!ops->vidioc_s_dv_preset) | ||
1850 | break; | ||
1851 | |||
1852 | dbgarg(cmd, "preset=%d\n", p->preset); | ||
1853 | ret = ops->vidioc_s_dv_preset(file, fh, p); | ||
1854 | break; | ||
1855 | } | ||
1856 | case VIDIOC_G_DV_PRESET: | ||
1857 | { | ||
1858 | struct v4l2_dv_preset *p = arg; | ||
1859 | |||
1860 | if (!ops->vidioc_g_dv_preset) | ||
1861 | break; | ||
1862 | |||
1863 | ret = ops->vidioc_g_dv_preset(file, fh, p); | ||
1864 | if (!ret) | ||
1865 | dbgarg(cmd, "preset=%d\n", p->preset); | ||
1866 | break; | ||
1867 | } | ||
1868 | case VIDIOC_QUERY_DV_PRESET: | ||
1869 | { | ||
1870 | struct v4l2_dv_preset *p = arg; | ||
1871 | |||
1872 | if (!ops->vidioc_query_dv_preset) | ||
1873 | break; | ||
1874 | |||
1875 | ret = ops->vidioc_query_dv_preset(file, fh, p); | ||
1876 | if (!ret) | ||
1877 | dbgarg(cmd, "preset=%d\n", p->preset); | ||
1878 | break; | ||
1879 | } | ||
1880 | case VIDIOC_S_DV_TIMINGS: | ||
1881 | { | ||
1882 | struct v4l2_dv_timings *p = arg; | ||
1883 | |||
1884 | if (!ops->vidioc_s_dv_timings) | ||
1885 | break; | ||
1886 | |||
1887 | switch (p->type) { | ||
1888 | case V4L2_DV_BT_656_1120: | ||
1889 | dbgarg2("bt-656/1120:interlaced=%d, pixelclock=%lld," | ||
1890 | " width=%d, height=%d, polarities=%x," | ||
1891 | " hfrontporch=%d, hsync=%d, hbackporch=%d," | ||
1892 | " vfrontporch=%d, vsync=%d, vbackporch=%d," | ||
1893 | " il_vfrontporch=%d, il_vsync=%d," | ||
1894 | " il_vbackporch=%d\n", | ||
1895 | p->bt.interlaced, p->bt.pixelclock, | ||
1896 | p->bt.width, p->bt.height, p->bt.polarities, | ||
1897 | p->bt.hfrontporch, p->bt.hsync, | ||
1898 | p->bt.hbackporch, p->bt.vfrontporch, | ||
1899 | p->bt.vsync, p->bt.vbackporch, | ||
1900 | p->bt.il_vfrontporch, p->bt.il_vsync, | ||
1901 | p->bt.il_vbackporch); | ||
1902 | ret = ops->vidioc_s_dv_timings(file, fh, p); | ||
1903 | break; | ||
1904 | default: | ||
1905 | dbgarg2("Unknown type %d!\n", p->type); | ||
1906 | break; | ||
1907 | } | ||
1908 | break; | ||
1909 | } | ||
1910 | case VIDIOC_G_DV_TIMINGS: | ||
1911 | { | ||
1912 | struct v4l2_dv_timings *p = arg; | ||
1913 | |||
1914 | if (!ops->vidioc_g_dv_timings) | ||
1915 | break; | ||
1916 | |||
1917 | ret = ops->vidioc_g_dv_timings(file, fh, p); | ||
1918 | if (!ret) { | ||
1919 | switch (p->type) { | ||
1920 | case V4L2_DV_BT_656_1120: | ||
1921 | dbgarg2("bt-656/1120:interlaced=%d," | ||
1922 | " pixelclock=%lld," | ||
1923 | " width=%d, height=%d, polarities=%x," | ||
1924 | " hfrontporch=%d, hsync=%d," | ||
1925 | " hbackporch=%d, vfrontporch=%d," | ||
1926 | " vsync=%d, vbackporch=%d," | ||
1927 | " il_vfrontporch=%d, il_vsync=%d," | ||
1928 | " il_vbackporch=%d\n", | ||
1929 | p->bt.interlaced, p->bt.pixelclock, | ||
1930 | p->bt.width, p->bt.height, | ||
1931 | p->bt.polarities, p->bt.hfrontporch, | ||
1932 | p->bt.hsync, p->bt.hbackporch, | ||
1933 | p->bt.vfrontporch, p->bt.vsync, | ||
1934 | p->bt.vbackporch, p->bt.il_vfrontporch, | ||
1935 | p->bt.il_vsync, p->bt.il_vbackporch); | ||
1936 | break; | ||
1937 | default: | ||
1938 | dbgarg2("Unknown type %d!\n", p->type); | ||
1939 | break; | ||
1940 | } | ||
1941 | } | ||
1942 | break; | ||
1943 | } | ||
1797 | 1944 | ||
1798 | default: | 1945 | default: |
1799 | { | 1946 | { |
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index d25f28461da..22c01097e8a 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c | |||
@@ -141,9 +141,11 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, | |||
141 | struct vm_area_struct *vma; | 141 | struct vm_area_struct *vma; |
142 | unsigned long prev_pfn, this_pfn; | 142 | unsigned long prev_pfn, this_pfn; |
143 | unsigned long pages_done, user_address; | 143 | unsigned long pages_done, user_address; |
144 | unsigned int offset; | ||
144 | int ret; | 145 | int ret; |
145 | 146 | ||
146 | mem->size = PAGE_ALIGN(vb->size); | 147 | offset = vb->baddr & ~PAGE_MASK; |
148 | mem->size = PAGE_ALIGN(vb->size + offset); | ||
147 | mem->is_userptr = 0; | 149 | mem->is_userptr = 0; |
148 | ret = -EINVAL; | 150 | ret = -EINVAL; |
149 | 151 | ||
@@ -166,7 +168,7 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, | |||
166 | break; | 168 | break; |
167 | 169 | ||
168 | if (pages_done == 0) | 170 | if (pages_done == 0) |
169 | mem->dma_handle = this_pfn << PAGE_SHIFT; | 171 | mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset; |
170 | else if (this_pfn != (prev_pfn + 1)) | 172 | else if (this_pfn != (prev_pfn + 1)) |
171 | ret = -EFAULT; | 173 | ret = -EFAULT; |
172 | 174 | ||
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index b034a81d2b1..a15d1e7cbed 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -4068,7 +4068,6 @@ static struct video_device vdev_template = { | |||
4068 | .fops = &vino_fops, | 4068 | .fops = &vino_fops, |
4069 | .ioctl_ops = &vino_ioctl_ops, | 4069 | .ioctl_ops = &vino_ioctl_ops, |
4070 | .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, | 4070 | .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, |
4071 | .minor = -1, | ||
4072 | }; | 4071 | }; |
4073 | 4072 | ||
4074 | static void vino_module_cleanup(int stage) | 4073 | static void vino_module_cleanup(int stage) |
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 7705fc6baf0..37632a06496 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -1148,7 +1148,8 @@ static int vivi_open(struct file *file) | |||
1148 | return -EBUSY; | 1148 | return -EBUSY; |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num, | 1151 | dprintk(dev, 1, "open %s type=%s users=%d\n", |
1152 | video_device_node_name(dev->vfd), | ||
1152 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); | 1153 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); |
1153 | 1154 | ||
1154 | /* allocate + initialize per filehandle data */ | 1155 | /* allocate + initialize per filehandle data */ |
@@ -1221,8 +1222,7 @@ static int vivi_close(struct file *file) | |||
1221 | struct vivi_fh *fh = file->private_data; | 1222 | struct vivi_fh *fh = file->private_data; |
1222 | struct vivi_dev *dev = fh->dev; | 1223 | struct vivi_dev *dev = fh->dev; |
1223 | struct vivi_dmaqueue *vidq = &dev->vidq; | 1224 | struct vivi_dmaqueue *vidq = &dev->vidq; |
1224 | 1225 | struct video_device *vdev = video_devdata(file); | |
1225 | int minor = video_devdata(file)->minor; | ||
1226 | 1226 | ||
1227 | vivi_stop_thread(vidq); | 1227 | vivi_stop_thread(vidq); |
1228 | videobuf_stop(&fh->vb_vidq); | 1228 | videobuf_stop(&fh->vb_vidq); |
@@ -1234,8 +1234,8 @@ static int vivi_close(struct file *file) | |||
1234 | dev->users--; | 1234 | dev->users--; |
1235 | mutex_unlock(&dev->mutex); | 1235 | mutex_unlock(&dev->mutex); |
1236 | 1236 | ||
1237 | dprintk(dev, 1, "close called (minor=%d, users=%d)\n", | 1237 | dprintk(dev, 1, "close called (dev=%s, users=%d)\n", |
1238 | minor, dev->users); | 1238 | video_device_node_name(vdev), dev->users); |
1239 | 1239 | ||
1240 | return 0; | 1240 | return 0; |
1241 | } | 1241 | } |
@@ -1296,7 +1296,6 @@ static struct video_device vivi_template = { | |||
1296 | .name = "vivi", | 1296 | .name = "vivi", |
1297 | .fops = &vivi_fops, | 1297 | .fops = &vivi_fops, |
1298 | .ioctl_ops = &vivi_ioctl_ops, | 1298 | .ioctl_ops = &vivi_ioctl_ops, |
1299 | .minor = -1, | ||
1300 | .release = video_device_release, | 1299 | .release = video_device_release, |
1301 | 1300 | ||
1302 | .tvnorms = V4L2_STD_525_60, | 1301 | .tvnorms = V4L2_STD_525_60, |
@@ -1317,8 +1316,8 @@ static int vivi_release(void) | |||
1317 | list_del(list); | 1316 | list_del(list); |
1318 | dev = list_entry(list, struct vivi_dev, vivi_devlist); | 1317 | dev = list_entry(list, struct vivi_dev, vivi_devlist); |
1319 | 1318 | ||
1320 | v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n", | 1319 | v4l2_info(&dev->v4l2_dev, "unregistering %s\n", |
1321 | dev->vfd->num); | 1320 | video_device_node_name(dev->vfd)); |
1322 | video_unregister_device(dev->vfd); | 1321 | video_unregister_device(dev->vfd); |
1323 | v4l2_device_unregister(&dev->v4l2_dev); | 1322 | v4l2_device_unregister(&dev->v4l2_dev); |
1324 | kfree(dev); | 1323 | kfree(dev); |
@@ -1372,15 +1371,12 @@ static int __init vivi_create_instance(int inst) | |||
1372 | /* Now that everything is fine, let's add it to device list */ | 1371 | /* Now that everything is fine, let's add it to device list */ |
1373 | list_add_tail(&dev->vivi_devlist, &vivi_devlist); | 1372 | list_add_tail(&dev->vivi_devlist, &vivi_devlist); |
1374 | 1373 | ||
1375 | snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", | ||
1376 | vivi_template.name, vfd->num); | ||
1377 | |||
1378 | if (video_nr >= 0) | 1374 | if (video_nr >= 0) |
1379 | video_nr++; | 1375 | video_nr++; |
1380 | 1376 | ||
1381 | dev->vfd = vfd; | 1377 | dev->vfd = vfd; |
1382 | v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n", | 1378 | v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n", |
1383 | vfd->num); | 1379 | video_device_node_name(vfd)); |
1384 | return 0; | 1380 | return 0; |
1385 | 1381 | ||
1386 | rel_vdev: | 1382 | rel_vdev: |
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 37fcdc447db..d807eea9175 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c | |||
@@ -2323,9 +2323,9 @@ static int w9968cf_sensor_init(struct w9968cf_device* cam) | |||
2323 | error: | 2323 | error: |
2324 | cam->sensor_initialized = 0; | 2324 | cam->sensor_initialized = 0; |
2325 | cam->sensor = CC_UNKNOWN; | 2325 | cam->sensor = CC_UNKNOWN; |
2326 | DBG(1, "Image sensor initialization failed for %s (/dev/video%d). " | 2326 | DBG(1, "Image sensor initialization failed for %s (%s). " |
2327 | "Try to detach and attach this device again", | 2327 | "Try to detach and attach this device again", |
2328 | symbolic(camlist, cam->id), cam->v4ldev->num) | 2328 | symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev)) |
2329 | return err; | 2329 | return err; |
2330 | } | 2330 | } |
2331 | 2331 | ||
@@ -2571,7 +2571,8 @@ static void w9968cf_release_resources(struct w9968cf_device* cam) | |||
2571 | { | 2571 | { |
2572 | mutex_lock(&w9968cf_devlist_mutex); | 2572 | mutex_lock(&w9968cf_devlist_mutex); |
2573 | 2573 | ||
2574 | DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->num) | 2574 | DBG(2, "V4L device deregistered: %s", |
2575 | video_device_node_name(cam->v4ldev)) | ||
2575 | 2576 | ||
2576 | video_unregister_device(cam->v4ldev); | 2577 | video_unregister_device(cam->v4ldev); |
2577 | list_del(&cam->v4llist); | 2578 | list_del(&cam->v4llist); |
@@ -2605,17 +2606,19 @@ static int w9968cf_open(struct file *filp) | |||
2605 | 2606 | ||
2606 | if (cam->sensor == CC_UNKNOWN) { | 2607 | if (cam->sensor == CC_UNKNOWN) { |
2607 | DBG(2, "No supported image sensor has been detected by the " | 2608 | DBG(2, "No supported image sensor has been detected by the " |
2608 | "'ovcamchip' module for the %s (/dev/video%d). Make " | 2609 | "'ovcamchip' module for the %s (%s). Make sure " |
2609 | "sure it is loaded *before* (re)connecting the camera.", | 2610 | "it is loaded *before* (re)connecting the camera.", |
2610 | symbolic(camlist, cam->id), cam->v4ldev->num) | 2611 | symbolic(camlist, cam->id), |
2612 | video_device_node_name(cam->v4ldev)) | ||
2611 | mutex_unlock(&cam->dev_mutex); | 2613 | mutex_unlock(&cam->dev_mutex); |
2612 | up_read(&w9968cf_disconnect); | 2614 | up_read(&w9968cf_disconnect); |
2613 | return -ENODEV; | 2615 | return -ENODEV; |
2614 | } | 2616 | } |
2615 | 2617 | ||
2616 | if (cam->users) { | 2618 | if (cam->users) { |
2617 | DBG(2, "%s (/dev/video%d) has been already occupied by '%s'", | 2619 | DBG(2, "%s (%s) has been already occupied by '%s'", |
2618 | symbolic(camlist, cam->id), cam->v4ldev->num, cam->command) | 2620 | symbolic(camlist, cam->id), |
2621 | video_device_node_name(cam->v4ldev), cam->command) | ||
2619 | if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) { | 2622 | if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) { |
2620 | mutex_unlock(&cam->dev_mutex); | 2623 | mutex_unlock(&cam->dev_mutex); |
2621 | up_read(&w9968cf_disconnect); | 2624 | up_read(&w9968cf_disconnect); |
@@ -2636,8 +2639,8 @@ static int w9968cf_open(struct file *filp) | |||
2636 | mutex_lock(&cam->dev_mutex); | 2639 | mutex_lock(&cam->dev_mutex); |
2637 | } | 2640 | } |
2638 | 2641 | ||
2639 | DBG(5, "Opening '%s', /dev/video%d ...", | 2642 | DBG(5, "Opening '%s', %s ...", |
2640 | symbolic(camlist, cam->id), cam->v4ldev->num) | 2643 | symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev)) |
2641 | 2644 | ||
2642 | cam->streaming = 0; | 2645 | cam->streaming = 0; |
2643 | cam->misconfigured = 0; | 2646 | cam->misconfigured = 0; |
@@ -2874,8 +2877,7 @@ static long w9968cf_v4l_ioctl(struct file *filp, | |||
2874 | .minwidth = cam->minwidth, | 2877 | .minwidth = cam->minwidth, |
2875 | .minheight = cam->minheight, | 2878 | .minheight = cam->minheight, |
2876 | }; | 2879 | }; |
2877 | sprintf(cap.name, "W996[87]CF USB Camera #%d", | 2880 | sprintf(cap.name, "W996[87]CF USB Camera"); |
2878 | cam->v4ldev->num); | ||
2879 | cap.maxwidth = (cam->upscaling && w9968cf_vpp) | 2881 | cap.maxwidth = (cam->upscaling && w9968cf_vpp) |
2880 | ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) | 2882 | ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) |
2881 | : cam->maxwidth; | 2883 | : cam->maxwidth; |
@@ -3485,7 +3487,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3485 | 3487 | ||
3486 | strcpy(cam->v4ldev->name, symbolic(camlist, mod_id)); | 3488 | strcpy(cam->v4ldev->name, symbolic(camlist, mod_id)); |
3487 | cam->v4ldev->fops = &w9968cf_fops; | 3489 | cam->v4ldev->fops = &w9968cf_fops; |
3488 | cam->v4ldev->minor = video_nr[dev_nr]; | ||
3489 | cam->v4ldev->release = video_device_release; | 3490 | cam->v4ldev->release = video_device_release; |
3490 | video_set_drvdata(cam->v4ldev, cam); | 3491 | video_set_drvdata(cam->v4ldev, cam); |
3491 | cam->v4ldev->v4l2_dev = &cam->v4l2_dev; | 3492 | cam->v4ldev->v4l2_dev = &cam->v4l2_dev; |
@@ -3501,7 +3502,8 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3501 | goto fail; | 3502 | goto fail; |
3502 | } | 3503 | } |
3503 | 3504 | ||
3504 | DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->num) | 3505 | DBG(2, "V4L device registered as %s", |
3506 | video_device_node_name(cam->v4ldev)) | ||
3505 | 3507 | ||
3506 | /* Set some basic constants */ | 3508 | /* Set some basic constants */ |
3507 | w9968cf_configure_camera(cam, udev, mod_id, dev_nr); | 3509 | w9968cf_configure_camera(cam, udev, mod_id, dev_nr); |
@@ -3557,10 +3559,10 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) | |||
3557 | wake_up_interruptible_all(&cam->open); | 3559 | wake_up_interruptible_all(&cam->open); |
3558 | 3560 | ||
3559 | if (cam->users) { | 3561 | if (cam->users) { |
3560 | DBG(2, "The device is open (/dev/video%d)! " | 3562 | DBG(2, "The device is open (%s)! " |
3561 | "Process name: %s. Deregistration and memory " | 3563 | "Process name: %s. Deregistration and memory " |
3562 | "deallocation are deferred on close.", | 3564 | "deallocation are deferred on close.", |
3563 | cam->v4ldev->num, cam->command) | 3565 | video_device_node_name(cam->v4ldev), cam->command) |
3564 | cam->misconfigured = 1; | 3566 | cam->misconfigured = 1; |
3565 | w9968cf_stop_transfer(cam); | 3567 | w9968cf_stop_transfer(cam); |
3566 | wake_up_interruptible(&cam->wait_queue); | 3568 | wake_up_interruptible(&cam->wait_queue); |
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index 312a71336fd..e44e4b5f3e5 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c | |||
@@ -538,8 +538,8 @@ static int zc0301_stream_interrupt(struct zc0301_device* cam) | |||
538 | else if (cam->stream != STREAM_OFF) { | 538 | else if (cam->stream != STREAM_OFF) { |
539 | cam->state |= DEV_MISCONFIGURED; | 539 | cam->state |= DEV_MISCONFIGURED; |
540 | DBG(1, "URB timeout reached. The camera is misconfigured. To " | 540 | DBG(1, "URB timeout reached. The camera is misconfigured. To " |
541 | "use it, close and open /dev/video%d again.", | 541 | "use it, close and open %s again.", |
542 | cam->v4ldev->num); | 542 | video_device_node_name(cam->v4ldev)); |
543 | return -EIO; | 543 | return -EIO; |
544 | } | 544 | } |
545 | 545 | ||
@@ -640,7 +640,8 @@ static void zc0301_release_resources(struct kref *kref) | |||
640 | { | 640 | { |
641 | struct zc0301_device *cam = container_of(kref, struct zc0301_device, | 641 | struct zc0301_device *cam = container_of(kref, struct zc0301_device, |
642 | kref); | 642 | kref); |
643 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->num); | 643 | DBG(2, "V4L2 device %s deregistered", |
644 | video_device_node_name(cam->v4ldev)); | ||
644 | video_set_drvdata(cam->v4ldev, NULL); | 645 | video_set_drvdata(cam->v4ldev, NULL); |
645 | video_unregister_device(cam->v4ldev); | 646 | video_unregister_device(cam->v4ldev); |
646 | usb_put_dev(cam->usbdev); | 647 | usb_put_dev(cam->usbdev); |
@@ -679,7 +680,8 @@ static int zc0301_open(struct file *filp) | |||
679 | } | 680 | } |
680 | 681 | ||
681 | if (cam->users) { | 682 | if (cam->users) { |
682 | DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->num); | 683 | DBG(2, "Device %s is busy...", |
684 | video_device_node_name(cam->v4ldev)); | ||
683 | DBG(3, "Simultaneous opens are not supported"); | 685 | DBG(3, "Simultaneous opens are not supported"); |
684 | if ((filp->f_flags & O_NONBLOCK) || | 686 | if ((filp->f_flags & O_NONBLOCK) || |
685 | (filp->f_flags & O_NDELAY)) { | 687 | (filp->f_flags & O_NDELAY)) { |
@@ -722,7 +724,8 @@ static int zc0301_open(struct file *filp) | |||
722 | cam->frame_count = 0; | 724 | cam->frame_count = 0; |
723 | zc0301_empty_framequeues(cam); | 725 | zc0301_empty_framequeues(cam); |
724 | 726 | ||
725 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->num); | 727 | DBG(3, "Video device %s is open", |
728 | video_device_node_name(cam->v4ldev)); | ||
726 | 729 | ||
727 | out: | 730 | out: |
728 | mutex_unlock(&cam->open_mutex); | 731 | mutex_unlock(&cam->open_mutex); |
@@ -746,7 +749,8 @@ static int zc0301_release(struct file *filp) | |||
746 | cam->users--; | 749 | cam->users--; |
747 | wake_up_interruptible_nr(&cam->wait_open, 1); | 750 | wake_up_interruptible_nr(&cam->wait_open, 1); |
748 | 751 | ||
749 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->num); | 752 | DBG(3, "Video device %s closed", |
753 | video_device_node_name(cam->v4ldev)); | ||
750 | 754 | ||
751 | kref_put(&cam->kref, zc0301_release_resources); | 755 | kref_put(&cam->kref, zc0301_release_resources); |
752 | 756 | ||
@@ -1276,8 +1280,8 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg) | |||
1276 | if (err) { /* atomic, no rollback in ioctl() */ | 1280 | if (err) { /* atomic, no rollback in ioctl() */ |
1277 | cam->state |= DEV_MISCONFIGURED; | 1281 | cam->state |= DEV_MISCONFIGURED; |
1278 | DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " | 1282 | DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To " |
1279 | "use the camera, close and open /dev/video%d again.", | 1283 | "use the camera, close and open %s again.", |
1280 | cam->v4ldev->num); | 1284 | video_device_node_name(cam->v4ldev)); |
1281 | return -EIO; | 1285 | return -EIO; |
1282 | } | 1286 | } |
1283 | 1287 | ||
@@ -1289,8 +1293,8 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg) | |||
1289 | nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) { | 1293 | nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) { |
1290 | cam->state |= DEV_MISCONFIGURED; | 1294 | cam->state |= DEV_MISCONFIGURED; |
1291 | DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " | 1295 | DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To " |
1292 | "use the camera, close and open /dev/video%d again.", | 1296 | "use the camera, close and open %s again.", |
1293 | cam->v4ldev->num); | 1297 | video_device_node_name(cam->v4ldev)); |
1294 | return -ENOMEM; | 1298 | return -ENOMEM; |
1295 | } | 1299 | } |
1296 | 1300 | ||
@@ -1471,8 +1475,8 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd, | |||
1471 | if (err) { /* atomic, no rollback in ioctl() */ | 1475 | if (err) { /* atomic, no rollback in ioctl() */ |
1472 | cam->state |= DEV_MISCONFIGURED; | 1476 | cam->state |= DEV_MISCONFIGURED; |
1473 | DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " | 1477 | DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To " |
1474 | "use the camera, close and open /dev/video%d again.", | 1478 | "use the camera, close and open %s again.", |
1475 | cam->v4ldev->num); | 1479 | video_device_node_name(cam->v4ldev)); |
1476 | return -EIO; | 1480 | return -EIO; |
1477 | } | 1481 | } |
1478 | 1482 | ||
@@ -1483,8 +1487,8 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd, | |||
1483 | nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) { | 1487 | nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) { |
1484 | cam->state |= DEV_MISCONFIGURED; | 1488 | cam->state |= DEV_MISCONFIGURED; |
1485 | DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " | 1489 | DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To " |
1486 | "use the camera, close and open /dev/video%d again.", | 1490 | "use the camera, close and open %s again.", |
1487 | cam->v4ldev->num); | 1491 | video_device_node_name(cam->v4ldev)); |
1488 | return -ENOMEM; | 1492 | return -ENOMEM; |
1489 | } | 1493 | } |
1490 | 1494 | ||
@@ -1530,8 +1534,8 @@ zc0301_vidioc_s_jpegcomp(struct zc0301_device* cam, void __user * arg) | |||
1530 | if (err) { /* atomic, no rollback in ioctl() */ | 1534 | if (err) { /* atomic, no rollback in ioctl() */ |
1531 | cam->state |= DEV_MISCONFIGURED; | 1535 | cam->state |= DEV_MISCONFIGURED; |
1532 | DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " | 1536 | DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware " |
1533 | "problems. To use the camera, close and open " | 1537 | "problems. To use the camera, close and open %s again.", |
1534 | "/dev/video%d again.", cam->v4ldev->num); | 1538 | video_device_node_name(cam->v4ldev)); |
1535 | return -EIO; | 1539 | return -EIO; |
1536 | } | 1540 | } |
1537 | 1541 | ||
@@ -1984,7 +1988,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
1984 | 1988 | ||
1985 | strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera"); | 1989 | strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera"); |
1986 | cam->v4ldev->fops = &zc0301_fops; | 1990 | cam->v4ldev->fops = &zc0301_fops; |
1987 | cam->v4ldev->minor = video_nr[dev_nr]; | ||
1988 | cam->v4ldev->release = video_device_release; | 1991 | cam->v4ldev->release = video_device_release; |
1989 | cam->v4ldev->parent = &udev->dev; | 1992 | cam->v4ldev->parent = &udev->dev; |
1990 | video_set_drvdata(cam->v4ldev, cam); | 1993 | video_set_drvdata(cam->v4ldev, cam); |
@@ -2003,7 +2006,8 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2003 | goto fail; | 2006 | goto fail; |
2004 | } | 2007 | } |
2005 | 2008 | ||
2006 | DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->num); | 2009 | DBG(2, "V4L2 device registered as %s", |
2010 | video_device_node_name(cam->v4ldev)); | ||
2007 | 2011 | ||
2008 | cam->module_param.force_munmap = force_munmap[dev_nr]; | 2012 | cam->module_param.force_munmap = force_munmap[dev_nr]; |
2009 | cam->module_param.frame_timeout = frame_timeout[dev_nr]; | 2013 | cam->module_param.frame_timeout = frame_timeout[dev_nr]; |
@@ -2040,9 +2044,9 @@ static void zc0301_usb_disconnect(struct usb_interface* intf) | |||
2040 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); | 2044 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); |
2041 | 2045 | ||
2042 | if (cam->users) { | 2046 | if (cam->users) { |
2043 | DBG(2, "Device /dev/video%d is open! Deregistration and " | 2047 | DBG(2, "Device %s is open! Deregistration and " |
2044 | "memory deallocation are deferred.", | 2048 | "memory deallocation are deferred.", |
2045 | cam->v4ldev->num); | 2049 | video_device_node_name(cam->v4ldev)); |
2046 | cam->state |= DEV_MISCONFIGURED; | 2050 | cam->state |= DEV_MISCONFIGURED; |
2047 | zc0301_stop_transfer(cam); | 2051 | zc0301_stop_transfer(cam); |
2048 | cam->state |= DEV_DISCONNECTED; | 2052 | cam->state |= DEV_DISCONNECTED; |
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index e9f72ca458f..2ddffed019e 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
@@ -3387,6 +3387,5 @@ struct video_device zoran_template __devinitdata = { | |||
3387 | .ioctl_ops = &zoran_ioctl_ops, | 3387 | .ioctl_ops = &zoran_ioctl_ops, |
3388 | .release = &zoran_vdev_release, | 3388 | .release = &zoran_vdev_release, |
3389 | .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, | 3389 | .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, |
3390 | .minor = -1 | ||
3391 | }; | 3390 | }; |
3392 | 3391 | ||
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index 2ef110b5221..f0eae83e3d8 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c | |||
@@ -1455,7 +1455,6 @@ static struct video_device zr364xx_template = { | |||
1455 | .fops = &zr364xx_fops, | 1455 | .fops = &zr364xx_fops, |
1456 | .ioctl_ops = &zr364xx_ioctl_ops, | 1456 | .ioctl_ops = &zr364xx_ioctl_ops, |
1457 | .release = video_device_release, | 1457 | .release = video_device_release, |
1458 | .minor = -1, | ||
1459 | }; | 1458 | }; |
1460 | 1459 | ||
1461 | 1460 | ||
@@ -1635,8 +1634,8 @@ static int zr364xx_probe(struct usb_interface *intf, | |||
1635 | 1634 | ||
1636 | spin_lock_init(&cam->slock); | 1635 | spin_lock_init(&cam->slock); |
1637 | 1636 | ||
1638 | dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n", | 1637 | dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n", |
1639 | cam->vdev->num); | 1638 | video_device_node_name(cam->vdev)); |
1640 | return 0; | 1639 | return 0; |
1641 | } | 1640 | } |
1642 | 1641 | ||
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c index f78b8912d90..89c8fe2997f 100644 --- a/drivers/staging/cx25821/cx25821-audups11.c +++ b/drivers/staging/cx25821/cx25821-audups11.c | |||
@@ -94,36 +94,20 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | 101 | ||
103 | lock_kernel(); | 102 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
104 | list_for_each(list, &cx25821_devlist) { | 103 | v4l2_type_names[type]); |
105 | h = list_entry(list, struct cx25821_dev, devlist); | ||
106 | |||
107 | if (h->video_dev[SRAM_CH11] | ||
108 | && h->video_dev[SRAM_CH11]->minor == minor) { | ||
109 | dev = h; | ||
110 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | if (NULL == dev) { | ||
115 | unlock_kernel(); | ||
116 | return -ENODEV; | ||
117 | } | ||
118 | |||
119 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
120 | 104 | ||
121 | /* allocate + initialize per filehandle data */ | 105 | /* allocate + initialize per filehandle data */ |
122 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 106 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
123 | if (NULL == fh) { | 107 | if (NULL == fh) |
124 | unlock_kernel(); | ||
125 | return -ENOMEM; | 108 | return -ENOMEM; |
126 | } | 109 | |
110 | lock_kernel(); | ||
127 | 111 | ||
128 | file->private_data = fh; | 112 | file->private_data = fh; |
129 | fh->dev = dev; | 113 | fh->dev = dev; |
@@ -427,7 +411,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
427 | struct video_device cx25821_video_template11 = { | 411 | struct video_device cx25821_video_template11 = { |
428 | .name = "cx25821-audioupstream", | 412 | .name = "cx25821-audioupstream", |
429 | .fops = &video_fops, | 413 | .fops = &video_fops, |
430 | .minor = -1, | ||
431 | .ioctl_ops = &video_ioctl_ops, | 414 | .ioctl_ops = &video_ioctl_ops, |
432 | .tvnorms = CX25821_NORMS, | 415 | .tvnorms = CX25821_NORMS, |
433 | .current_norm = V4L2_STD_NTSC_M, | 416 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c index 8834bc80a5a..c7c14c7698a 100644 --- a/drivers/staging/cx25821/cx25821-video.c +++ b/drivers/staging/cx25821/cx25821-video.c | |||
@@ -184,11 +184,11 @@ struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, | |||
184 | if (NULL == vfd) | 184 | if (NULL == vfd) |
185 | return NULL; | 185 | return NULL; |
186 | *vfd = *template; | 186 | *vfd = *template; |
187 | vfd->minor = -1; | ||
188 | vfd->v4l2_dev = &dev->v4l2_dev; | 187 | vfd->v4l2_dev = &dev->v4l2_dev; |
189 | vfd->release = video_device_release; | 188 | vfd->release = video_device_release; |
190 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, | 189 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, |
191 | cx25821_boards[dev->board].name); | 190 | cx25821_boards[dev->board].name); |
191 | video_set_drvdata(vfd, dev); | ||
192 | return vfd; | 192 | return vfd; |
193 | } | 193 | } |
194 | 194 | ||
@@ -424,7 +424,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) | |||
424 | void cx25821_videoioctl_unregister(struct cx25821_dev *dev) | 424 | void cx25821_videoioctl_unregister(struct cx25821_dev *dev) |
425 | { | 425 | { |
426 | if (dev->ioctl_dev) { | 426 | if (dev->ioctl_dev) { |
427 | if (dev->ioctl_dev->minor != -1) | 427 | if (video_is_registered(dev->ioctl_dev)) |
428 | video_unregister_device(dev->ioctl_dev); | 428 | video_unregister_device(dev->ioctl_dev); |
429 | else | 429 | else |
430 | video_device_release(dev->ioctl_dev); | 430 | video_device_release(dev->ioctl_dev); |
@@ -438,7 +438,7 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) | |||
438 | cx_clear(PCI_INT_MSK, 1); | 438 | cx_clear(PCI_INT_MSK, 1); |
439 | 439 | ||
440 | if (dev->video_dev[chan_num]) { | 440 | if (dev->video_dev[chan_num]) { |
441 | if (-1 != dev->video_dev[chan_num]->minor) | 441 | if (video_is_registered(dev->video_dev[chan_num])) |
442 | video_unregister_device(dev->video_dev[chan_num]); | 442 | video_unregister_device(dev->video_dev[chan_num]); |
443 | else | 443 | else |
444 | video_device_release(dev->video_dev[chan_num]); | 444 | video_device_release(dev->video_dev[chan_num]); |
diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c index 950fac1d700..ad7a6912911 100644 --- a/drivers/staging/cx25821/cx25821-video0.c +++ b/drivers/staging/cx25821/cx25821-video0.c | |||
@@ -94,37 +94,21 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | u32 pix_format; | 101 | u32 pix_format; |
103 | 102 | ||
104 | lock_kernel(); | 103 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
105 | list_for_each(list, &cx25821_devlist) { | 104 | v4l2_type_names[type]); |
106 | h = list_entry(list, struct cx25821_dev, devlist); | ||
107 | |||
108 | if (h->video_dev[SRAM_CH00] | ||
109 | && h->video_dev[SRAM_CH00]->minor == minor) { | ||
110 | dev = h; | ||
111 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (NULL == dev) { | ||
116 | unlock_kernel(); | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | |||
120 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
121 | 105 | ||
122 | /* allocate + initialize per filehandle data */ | 106 | /* allocate + initialize per filehandle data */ |
123 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 107 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
124 | if (NULL == fh) { | 108 | if (NULL == fh) |
125 | unlock_kernel(); | ||
126 | return -ENOMEM; | 109 | return -ENOMEM; |
127 | } | 110 | |
111 | lock_kernel(); | ||
128 | 112 | ||
129 | file->private_data = fh; | 113 | file->private_data = fh; |
130 | fh->dev = dev; | 114 | fh->dev = dev; |
@@ -444,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
444 | struct video_device cx25821_video_template0 = { | 428 | struct video_device cx25821_video_template0 = { |
445 | .name = "cx25821-video", | 429 | .name = "cx25821-video", |
446 | .fops = &video_fops, | 430 | .fops = &video_fops, |
447 | .minor = -1, | ||
448 | .ioctl_ops = &video_ioctl_ops, | 431 | .ioctl_ops = &video_ioctl_ops, |
449 | .tvnorms = CX25821_NORMS, | 432 | .tvnorms = CX25821_NORMS, |
450 | .current_norm = V4L2_STD_NTSC_M, | 433 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c index a4dddc684ad..e3f3c4ac790 100644 --- a/drivers/staging/cx25821/cx25821-video1.c +++ b/drivers/staging/cx25821/cx25821-video1.c | |||
@@ -94,37 +94,21 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | u32 pix_format; | 101 | u32 pix_format; |
103 | 102 | ||
104 | lock_kernel(); | 103 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
105 | list_for_each(list, &cx25821_devlist) { | 104 | v4l2_type_names[type]); |
106 | h = list_entry(list, struct cx25821_dev, devlist); | ||
107 | |||
108 | if (h->video_dev[SRAM_CH01] | ||
109 | && h->video_dev[SRAM_CH01]->minor == minor) { | ||
110 | dev = h; | ||
111 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (NULL == dev) { | ||
116 | unlock_kernel(); | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | |||
120 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
121 | 105 | ||
122 | /* allocate + initialize per filehandle data */ | 106 | /* allocate + initialize per filehandle data */ |
123 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 107 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
124 | if (NULL == fh) { | 108 | if (NULL == fh) |
125 | unlock_kernel(); | ||
126 | return -ENOMEM; | 109 | return -ENOMEM; |
127 | } | 110 | |
111 | lock_kernel(); | ||
128 | 112 | ||
129 | file->private_data = fh; | 113 | file->private_data = fh; |
130 | fh->dev = dev; | 114 | fh->dev = dev; |
@@ -444,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
444 | struct video_device cx25821_video_template1 = { | 428 | struct video_device cx25821_video_template1 = { |
445 | .name = "cx25821-video", | 429 | .name = "cx25821-video", |
446 | .fops = &video_fops, | 430 | .fops = &video_fops, |
447 | .minor = -1, | ||
448 | .ioctl_ops = &video_ioctl_ops, | 431 | .ioctl_ops = &video_ioctl_ops, |
449 | .tvnorms = CX25821_NORMS, | 432 | .tvnorms = CX25821_NORMS, |
450 | .current_norm = V4L2_STD_NTSC_M, | 433 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c index 8e04e253f5d..36fb855a497 100644 --- a/drivers/staging/cx25821/cx25821-video2.c +++ b/drivers/staging/cx25821/cx25821-video2.c | |||
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | u32 pix_format; | 101 | u32 pix_format; |
103 | 102 | ||
104 | lock_kernel(); | 103 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
105 | list_for_each(list, &cx25821_devlist) { | 104 | v4l2_type_names[type]); |
106 | h = list_entry(list, struct cx25821_dev, devlist); | ||
107 | |||
108 | if (h->video_dev[SRAM_CH02] | ||
109 | && h->video_dev[SRAM_CH02]->minor == minor) { | ||
110 | dev = h; | ||
111 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (NULL == dev) { | ||
116 | unlock_kernel(); | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | |||
120 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
121 | 105 | ||
122 | /* allocate + initialize per filehandle data */ | 106 | /* allocate + initialize per filehandle data */ |
123 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 107 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
124 | if (NULL == fh) { | 108 | if (NULL == fh) |
125 | unlock_kernel(); | ||
126 | return -ENOMEM; | 109 | return -ENOMEM; |
127 | } | 110 | |
111 | lock_kernel(); | ||
112 | |||
128 | file->private_data = fh; | 113 | file->private_data = fh; |
129 | fh->dev = dev; | 114 | fh->dev = dev; |
130 | fh->type = type; | 115 | fh->type = type; |
@@ -445,7 +430,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
445 | struct video_device cx25821_video_template2 = { | 430 | struct video_device cx25821_video_template2 = { |
446 | .name = "cx25821-video", | 431 | .name = "cx25821-video", |
447 | .fops = &video_fops, | 432 | .fops = &video_fops, |
448 | .minor = -1, | ||
449 | .ioctl_ops = &video_ioctl_ops, | 433 | .ioctl_ops = &video_ioctl_ops, |
450 | .tvnorms = CX25821_NORMS, | 434 | .tvnorms = CX25821_NORMS, |
451 | .current_norm = V4L2_STD_NTSC_M, | 435 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c index 8801a8ead90..1e0f10abdbc 100644 --- a/drivers/staging/cx25821/cx25821-video3.c +++ b/drivers/staging/cx25821/cx25821-video3.c | |||
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | u32 pix_format; | 101 | u32 pix_format; |
103 | 102 | ||
104 | lock_kernel(); | 103 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
105 | list_for_each(list, &cx25821_devlist) { | 104 | v4l2_type_names[type]); |
106 | h = list_entry(list, struct cx25821_dev, devlist); | ||
107 | |||
108 | if (h->video_dev[SRAM_CH03] | ||
109 | && h->video_dev[SRAM_CH03]->minor == minor) { | ||
110 | dev = h; | ||
111 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (NULL == dev) { | ||
116 | unlock_kernel(); | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | |||
120 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
121 | 105 | ||
122 | /* allocate + initialize per filehandle data */ | 106 | /* allocate + initialize per filehandle data */ |
123 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 107 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
124 | if (NULL == fh) { | 108 | if (NULL == fh) |
125 | unlock_kernel(); | ||
126 | return -ENOMEM; | 109 | return -ENOMEM; |
127 | } | 110 | |
111 | lock_kernel(); | ||
112 | |||
128 | file->private_data = fh; | 113 | file->private_data = fh; |
129 | fh->dev = dev; | 114 | fh->dev = dev; |
130 | fh->type = type; | 115 | fh->type = type; |
@@ -444,7 +429,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
444 | struct video_device cx25821_video_template3 = { | 429 | struct video_device cx25821_video_template3 = { |
445 | .name = "cx25821-video", | 430 | .name = "cx25821-video", |
446 | .fops = &video_fops, | 431 | .fops = &video_fops, |
447 | .minor = -1, | ||
448 | .ioctl_ops = &video_ioctl_ops, | 432 | .ioctl_ops = &video_ioctl_ops, |
449 | .tvnorms = CX25821_NORMS, | 433 | .tvnorms = CX25821_NORMS, |
450 | .current_norm = V4L2_STD_NTSC_M, | 434 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c index ab0d747138a..0cbe7a79d8c 100644 --- a/drivers/staging/cx25821/cx25821-video4.c +++ b/drivers/staging/cx25821/cx25821-video4.c | |||
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | u32 pix_format; | 101 | u32 pix_format; |
103 | 102 | ||
104 | lock_kernel(); | 103 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
105 | list_for_each(list, &cx25821_devlist) { | 104 | v4l2_type_names[type]); |
106 | h = list_entry(list, struct cx25821_dev, devlist); | ||
107 | |||
108 | if (h->video_dev[SRAM_CH04] | ||
109 | && h->video_dev[SRAM_CH04]->minor == minor) { | ||
110 | dev = h; | ||
111 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (NULL == dev) { | ||
116 | unlock_kernel(); | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | |||
120 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
121 | 105 | ||
122 | /* allocate + initialize per filehandle data */ | 106 | /* allocate + initialize per filehandle data */ |
123 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 107 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
124 | if (NULL == fh) { | 108 | if (NULL == fh) |
125 | unlock_kernel(); | ||
126 | return -ENOMEM; | 109 | return -ENOMEM; |
127 | } | 110 | |
111 | lock_kernel(); | ||
112 | |||
128 | file->private_data = fh; | 113 | file->private_data = fh; |
129 | fh->dev = dev; | 114 | fh->dev = dev; |
130 | fh->type = type; | 115 | fh->type = type; |
@@ -443,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
443 | struct video_device cx25821_video_template4 = { | 428 | struct video_device cx25821_video_template4 = { |
444 | .name = "cx25821-video", | 429 | .name = "cx25821-video", |
445 | .fops = &video_fops, | 430 | .fops = &video_fops, |
446 | .minor = -1, | ||
447 | .ioctl_ops = &video_ioctl_ops, | 431 | .ioctl_ops = &video_ioctl_ops, |
448 | .tvnorms = CX25821_NORMS, | 432 | .tvnorms = CX25821_NORMS, |
449 | .current_norm = V4L2_STD_NTSC_M, | 433 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c index 7ef0b971f5c..5dc08adc12e 100644 --- a/drivers/staging/cx25821/cx25821-video5.c +++ b/drivers/staging/cx25821/cx25821-video5.c | |||
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | u32 pix_format; | 101 | u32 pix_format; |
103 | 102 | ||
104 | lock_kernel(); | 103 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
105 | list_for_each(list, &cx25821_devlist) { | 104 | v4l2_type_names[type]); |
106 | h = list_entry(list, struct cx25821_dev, devlist); | ||
107 | |||
108 | if (h->video_dev[SRAM_CH05] | ||
109 | && h->video_dev[SRAM_CH05]->minor == minor) { | ||
110 | dev = h; | ||
111 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (NULL == dev) { | ||
116 | unlock_kernel(); | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | |||
120 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
121 | 105 | ||
122 | /* allocate + initialize per filehandle data */ | 106 | /* allocate + initialize per filehandle data */ |
123 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 107 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
124 | if (NULL == fh) { | 108 | if (NULL == fh) |
125 | unlock_kernel(); | ||
126 | return -ENOMEM; | 109 | return -ENOMEM; |
127 | } | 110 | |
111 | lock_kernel(); | ||
112 | |||
128 | file->private_data = fh; | 113 | file->private_data = fh; |
129 | fh->dev = dev; | 114 | fh->dev = dev; |
130 | fh->type = type; | 115 | fh->type = type; |
@@ -443,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
443 | struct video_device cx25821_video_template5 = { | 428 | struct video_device cx25821_video_template5 = { |
444 | .name = "cx25821-video", | 429 | .name = "cx25821-video", |
445 | .fops = &video_fops, | 430 | .fops = &video_fops, |
446 | .minor = -1, | ||
447 | .ioctl_ops = &video_ioctl_ops, | 431 | .ioctl_ops = &video_ioctl_ops, |
448 | .tvnorms = CX25821_NORMS, | 432 | .tvnorms = CX25821_NORMS, |
449 | .current_norm = V4L2_STD_NTSC_M, | 433 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c index 3c41b49e2ea..2938ad3ad3c 100644 --- a/drivers/staging/cx25821/cx25821-video6.c +++ b/drivers/staging/cx25821/cx25821-video6.c | |||
@@ -94,37 +94,22 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | u32 pix_format; | 101 | u32 pix_format; |
103 | 102 | ||
104 | lock_kernel(); | 103 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
105 | list_for_each(list, &cx25821_devlist) { | 104 | v4l2_type_names[type]); |
106 | h = list_entry(list, struct cx25821_dev, devlist); | ||
107 | |||
108 | if (h->video_dev[SRAM_CH06] | ||
109 | && h->video_dev[SRAM_CH06]->minor == minor) { | ||
110 | dev = h; | ||
111 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | if (NULL == dev) { | ||
116 | unlock_kernel(); | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | |||
120 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
121 | 105 | ||
122 | /* allocate + initialize per filehandle data */ | 106 | /* allocate + initialize per filehandle data */ |
123 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 107 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
124 | if (NULL == fh) { | 108 | if (NULL == fh) |
125 | unlock_kernel(); | ||
126 | return -ENOMEM; | 109 | return -ENOMEM; |
127 | } | 110 | |
111 | lock_kernel(); | ||
112 | |||
128 | file->private_data = fh; | 113 | file->private_data = fh; |
129 | fh->dev = dev; | 114 | fh->dev = dev; |
130 | fh->type = type; | 115 | fh->type = type; |
@@ -443,7 +428,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
443 | struct video_device cx25821_video_template6 = { | 428 | struct video_device cx25821_video_template6 = { |
444 | .name = "cx25821-video", | 429 | .name = "cx25821-video", |
445 | .fops = &video_fops, | 430 | .fops = &video_fops, |
446 | .minor = -1, | ||
447 | .ioctl_ops = &video_ioctl_ops, | 431 | .ioctl_ops = &video_ioctl_ops, |
448 | .tvnorms = CX25821_NORMS, | 432 | .tvnorms = CX25821_NORMS, |
449 | .current_norm = V4L2_STD_NTSC_M, | 433 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c index 625c9b78a9c..458e525d72a 100644 --- a/drivers/staging/cx25821/cx25821-video7.c +++ b/drivers/staging/cx25821/cx25821-video7.c | |||
@@ -93,37 +93,22 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
93 | 93 | ||
94 | static int video_open(struct file *file) | 94 | static int video_open(struct file *file) |
95 | { | 95 | { |
96 | int minor = video_devdata(file)->minor; | 96 | struct video_device *vdev = video_devdata(file); |
97 | struct cx25821_dev *h, *dev = NULL; | 97 | struct cx25821_dev *dev = video_drvdata(file); |
98 | struct cx25821_fh *fh; | 98 | struct cx25821_fh *fh; |
99 | struct list_head *list; | 99 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
100 | enum v4l2_buf_type type = 0; | ||
101 | u32 pix_format; | 100 | u32 pix_format; |
102 | 101 | ||
103 | lock_kernel(); | 102 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
104 | list_for_each(list, &cx25821_devlist) { | 103 | v4l2_type_names[type]); |
105 | h = list_entry(list, struct cx25821_dev, devlist); | ||
106 | |||
107 | if (h->video_dev[SRAM_CH07] | ||
108 | && h->video_dev[SRAM_CH07]->minor == minor) { | ||
109 | dev = h; | ||
110 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | if (NULL == dev) { | ||
115 | unlock_kernel(); | ||
116 | return -ENODEV; | ||
117 | } | ||
118 | |||
119 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
120 | 104 | ||
121 | /* allocate + initialize per filehandle data */ | 105 | /* allocate + initialize per filehandle data */ |
122 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 106 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
123 | if (NULL == fh) { | 107 | if (NULL == fh) |
124 | unlock_kernel(); | ||
125 | return -ENOMEM; | 108 | return -ENOMEM; |
126 | } | 109 | |
110 | lock_kernel(); | ||
111 | |||
127 | file->private_data = fh; | 112 | file->private_data = fh; |
128 | fh->dev = dev; | 113 | fh->dev = dev; |
129 | fh->type = type; | 114 | fh->type = type; |
@@ -442,7 +427,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
442 | struct video_device cx25821_video_template7 = { | 427 | struct video_device cx25821_video_template7 = { |
443 | .name = "cx25821-video", | 428 | .name = "cx25821-video", |
444 | .fops = &video_fops, | 429 | .fops = &video_fops, |
445 | .minor = -1, | ||
446 | .ioctl_ops = &video_ioctl_ops, | 430 | .ioctl_ops = &video_ioctl_ops, |
447 | .tvnorms = CX25821_NORMS, | 431 | .tvnorms = CX25821_NORMS, |
448 | .current_norm = V4L2_STD_NTSC_M, | 432 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c index 2a312ce78c6..1da52b54a45 100644 --- a/drivers/staging/cx25821/cx25821-videoioctl.c +++ b/drivers/staging/cx25821/cx25821-videoioctl.c | |||
@@ -94,36 +94,21 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | u32 pix_format; | 101 | u32 pix_format; |
103 | 102 | ||
104 | lock_kernel(); | 103 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
105 | list_for_each(list, &cx25821_devlist) { | 104 | v4l2_type_names[type]); |
106 | h = list_entry(list, struct cx25821_dev, devlist); | ||
107 | |||
108 | if (h->ioctl_dev && h->ioctl_dev->minor == minor) { | ||
109 | dev = h; | ||
110 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | if (NULL == dev) { | ||
115 | unlock_kernel(); | ||
116 | return -ENODEV; | ||
117 | } | ||
118 | |||
119 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
120 | 105 | ||
121 | /* allocate + initialize per filehandle data */ | 106 | /* allocate + initialize per filehandle data */ |
122 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 107 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
123 | if (NULL == fh) { | 108 | if (NULL == fh) |
124 | unlock_kernel(); | ||
125 | return -ENOMEM; | 109 | return -ENOMEM; |
126 | } | 110 | |
111 | lock_kernel(); | ||
127 | 112 | ||
128 | file->private_data = fh; | 113 | file->private_data = fh; |
129 | fh->dev = dev; | 114 | fh->dev = dev; |
@@ -489,7 +474,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
489 | struct video_device cx25821_videoioctl_template = { | 474 | struct video_device cx25821_videoioctl_template = { |
490 | .name = "cx25821-videoioctl", | 475 | .name = "cx25821-videoioctl", |
491 | .fops = &video_fops, | 476 | .fops = &video_fops, |
492 | .minor = -1, | ||
493 | .ioctl_ops = &video_ioctl_ops, | 477 | .ioctl_ops = &video_ioctl_ops, |
494 | .tvnorms = CX25821_NORMS, | 478 | .tvnorms = CX25821_NORMS, |
495 | .current_norm = V4L2_STD_NTSC_M, | 479 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c index 77b63b06040..b76d9f62c3d 100644 --- a/drivers/staging/cx25821/cx25821-vidups10.c +++ b/drivers/staging/cx25821/cx25821-vidups10.c | |||
@@ -94,36 +94,20 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | 101 | ||
103 | lock_kernel(); | 102 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
104 | list_for_each(list, &cx25821_devlist) { | 103 | v4l2_type_names[type]); |
105 | h = list_entry(list, struct cx25821_dev, devlist); | ||
106 | |||
107 | if (h->video_dev[SRAM_CH10] | ||
108 | && h->video_dev[SRAM_CH10]->minor == minor) { | ||
109 | dev = h; | ||
110 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | if (NULL == dev) { | ||
115 | unlock_kernel(); | ||
116 | return -ENODEV; | ||
117 | } | ||
118 | |||
119 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
120 | 104 | ||
121 | /* allocate + initialize per filehandle data */ | 105 | /* allocate + initialize per filehandle data */ |
122 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 106 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
123 | if (NULL == fh) { | 107 | if (NULL == fh) |
124 | unlock_kernel(); | ||
125 | return -ENOMEM; | 108 | return -ENOMEM; |
126 | } | 109 | |
110 | lock_kernel(); | ||
127 | 111 | ||
128 | file->private_data = fh; | 112 | file->private_data = fh; |
129 | fh->dev = dev; | 113 | fh->dev = dev; |
@@ -428,7 +412,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
428 | struct video_device cx25821_video_template10 = { | 412 | struct video_device cx25821_video_template10 = { |
429 | .name = "cx25821-upstream10", | 413 | .name = "cx25821-upstream10", |
430 | .fops = &video_fops, | 414 | .fops = &video_fops, |
431 | .minor = -1, | ||
432 | .ioctl_ops = &video_ioctl_ops, | 415 | .ioctl_ops = &video_ioctl_ops, |
433 | .tvnorms = CX25821_NORMS, | 416 | .tvnorms = CX25821_NORMS, |
434 | .current_norm = V4L2_STD_NTSC_M, | 417 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c index 75c8c1eed2d..1580da3b29a 100644 --- a/drivers/staging/cx25821/cx25821-vidups9.c +++ b/drivers/staging/cx25821/cx25821-vidups9.c | |||
@@ -94,36 +94,20 @@ static struct videobuf_queue_ops cx25821_video_qops = { | |||
94 | 94 | ||
95 | static int video_open(struct file *file) | 95 | static int video_open(struct file *file) |
96 | { | 96 | { |
97 | int minor = video_devdata(file)->minor; | 97 | struct video_device *vdev = video_devdata(file); |
98 | struct cx25821_dev *h, *dev = NULL; | 98 | struct cx25821_dev *dev = video_drvdata(file); |
99 | struct cx25821_fh *fh; | 99 | struct cx25821_fh *fh; |
100 | struct list_head *list; | 100 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
101 | enum v4l2_buf_type type = 0; | ||
102 | 101 | ||
103 | lock_kernel(); | 102 | printk("open dev=%s type=%s\n", video_device_node_name(vdev), |
104 | list_for_each(list, &cx25821_devlist) { | 103 | v4l2_type_names[type]); |
105 | h = list_entry(list, struct cx25821_dev, devlist); | ||
106 | |||
107 | if (h->video_dev[SRAM_CH09] | ||
108 | && h->video_dev[SRAM_CH09]->minor == minor) { | ||
109 | dev = h; | ||
110 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | if (NULL == dev) { | ||
115 | unlock_kernel(); | ||
116 | return -ENODEV; | ||
117 | } | ||
118 | |||
119 | printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]); | ||
120 | 104 | ||
121 | /* allocate + initialize per filehandle data */ | 105 | /* allocate + initialize per filehandle data */ |
122 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 106 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
123 | if (NULL == fh) { | 107 | if (NULL == fh) |
124 | unlock_kernel(); | ||
125 | return -ENOMEM; | 108 | return -ENOMEM; |
126 | } | 109 | |
110 | lock_kernel(); | ||
127 | 111 | ||
128 | file->private_data = fh; | 112 | file->private_data = fh; |
129 | fh->dev = dev; | 113 | fh->dev = dev; |
@@ -426,7 +410,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
426 | struct video_device cx25821_video_template9 = { | 410 | struct video_device cx25821_video_template9 = { |
427 | .name = "cx25821-upstream9", | 411 | .name = "cx25821-upstream9", |
428 | .fops = &video_fops, | 412 | .fops = &video_fops, |
429 | .minor = -1, | ||
430 | .ioctl_ops = &video_ioctl_ops, | 413 | .ioctl_ops = &video_ioctl_ops, |
431 | .tvnorms = CX25821_NORMS, | 414 | .tvnorms = CX25821_NORMS, |
432 | .current_norm = V4L2_STD_NTSC_M, | 415 | .current_norm = V4L2_STD_NTSC_M, |
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c index b18d8e2d4c5..3af79242313 100644 --- a/drivers/staging/go7007/go7007-v4l2.c +++ b/drivers/staging/go7007/go7007-v4l2.c | |||
@@ -1787,7 +1787,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1787 | static struct video_device go7007_template = { | 1787 | static struct video_device go7007_template = { |
1788 | .name = "go7007", | 1788 | .name = "go7007", |
1789 | .fops = &go7007_fops, | 1789 | .fops = &go7007_fops, |
1790 | .minor = -1, | ||
1791 | .release = go7007_vfl_release, | 1790 | .release = go7007_vfl_release, |
1792 | .ioctl_ops = &video_ioctl_ops, | 1791 | .ioctl_ops = &video_ioctl_ops, |
1793 | .tvnorms = V4L2_STD_ALL, | 1792 | .tvnorms = V4L2_STD_ALL, |
@@ -1817,8 +1816,8 @@ int go7007_v4l2_init(struct go7007 *go) | |||
1817 | } | 1816 | } |
1818 | video_set_drvdata(go->video_dev, go); | 1817 | video_set_drvdata(go->video_dev, go); |
1819 | ++go->ref_count; | 1818 | ++go->ref_count; |
1820 | printk(KERN_INFO "%s: registered device video%d [v4l2]\n", | 1819 | printk(KERN_INFO "%s: registered device %s [v4l2]\n", |
1821 | go->video_dev->name, go->video_dev->num); | 1820 | go->video_dev->name, video_device_node_name(go->video_dev)); |
1822 | 1821 | ||
1823 | return 0; | 1822 | return 0; |
1824 | } | 1823 | } |
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 32b92298fd7..d4962a782b8 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h | |||
@@ -294,6 +294,7 @@ struct v4l2_pix_format { | |||
294 | 294 | ||
295 | /* Grey formats */ | 295 | /* Grey formats */ |
296 | #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ | 296 | #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ |
297 | #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ | ||
297 | #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ | 298 | #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ |
298 | 299 | ||
299 | /* Palette formats */ | 300 | /* Palette formats */ |
@@ -329,7 +330,11 @@ struct v4l2_pix_format { | |||
329 | #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ | 330 | #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ |
330 | #define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ | 331 | #define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ |
331 | #define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ | 332 | #define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ |
332 | #define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10bit raw bayer */ | 333 | #define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ |
334 | #define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ | ||
335 | #define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ | ||
336 | #define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ | ||
337 | #define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ | ||
333 | /* 10bit raw bayer DPCM compressed to 8 bits */ | 338 | /* 10bit raw bayer DPCM compressed to 8 bits */ |
334 | #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') | 339 | #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') |
335 | /* | 340 | /* |
@@ -732,6 +737,99 @@ struct v4l2_standard { | |||
732 | }; | 737 | }; |
733 | 738 | ||
734 | /* | 739 | /* |
740 | * V I D E O T I M I N G S D V P R E S E T | ||
741 | */ | ||
742 | struct v4l2_dv_preset { | ||
743 | __u32 preset; | ||
744 | __u32 reserved[4]; | ||
745 | }; | ||
746 | |||
747 | /* | ||
748 | * D V P R E S E T S E N U M E R A T I O N | ||
749 | */ | ||
750 | struct v4l2_dv_enum_preset { | ||
751 | __u32 index; | ||
752 | __u32 preset; | ||
753 | __u8 name[32]; /* Name of the preset timing */ | ||
754 | __u32 width; | ||
755 | __u32 height; | ||
756 | __u32 reserved[4]; | ||
757 | }; | ||
758 | |||
759 | /* | ||
760 | * D V P R E S E T V A L U E S | ||
761 | */ | ||
762 | #define V4L2_DV_INVALID 0 | ||
763 | #define V4L2_DV_480P59_94 1 /* BT.1362 */ | ||
764 | #define V4L2_DV_576P50 2 /* BT.1362 */ | ||
765 | #define V4L2_DV_720P24 3 /* SMPTE 296M */ | ||
766 | #define V4L2_DV_720P25 4 /* SMPTE 296M */ | ||
767 | #define V4L2_DV_720P30 5 /* SMPTE 296M */ | ||
768 | #define V4L2_DV_720P50 6 /* SMPTE 296M */ | ||
769 | #define V4L2_DV_720P59_94 7 /* SMPTE 274M */ | ||
770 | #define V4L2_DV_720P60 8 /* SMPTE 274M/296M */ | ||
771 | #define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */ | ||
772 | #define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */ | ||
773 | #define V4L2_DV_1080I25 11 /* BT.1120 */ | ||
774 | #define V4L2_DV_1080I50 12 /* SMPTE 296M */ | ||
775 | #define V4L2_DV_1080I60 13 /* SMPTE 296M */ | ||
776 | #define V4L2_DV_1080P24 14 /* SMPTE 296M */ | ||
777 | #define V4L2_DV_1080P25 15 /* SMPTE 296M */ | ||
778 | #define V4L2_DV_1080P30 16 /* SMPTE 296M */ | ||
779 | #define V4L2_DV_1080P50 17 /* BT.1120 */ | ||
780 | #define V4L2_DV_1080P60 18 /* BT.1120 */ | ||
781 | |||
782 | /* | ||
783 | * D V B T T I M I N G S | ||
784 | */ | ||
785 | |||
786 | /* BT.656/BT.1120 timing data */ | ||
787 | struct v4l2_bt_timings { | ||
788 | __u32 width; /* width in pixels */ | ||
789 | __u32 height; /* height in lines */ | ||
790 | __u32 interlaced; /* Interlaced or progressive */ | ||
791 | __u32 polarities; /* Positive or negative polarity */ | ||
792 | __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ | ||
793 | __u32 hfrontporch; /* Horizpontal front porch in pixels */ | ||
794 | __u32 hsync; /* Horizontal Sync length in pixels */ | ||
795 | __u32 hbackporch; /* Horizontal back porch in pixels */ | ||
796 | __u32 vfrontporch; /* Vertical front porch in pixels */ | ||
797 | __u32 vsync; /* Vertical Sync length in lines */ | ||
798 | __u32 vbackporch; /* Vertical back porch in lines */ | ||
799 | __u32 il_vfrontporch; /* Vertical front porch for bottom field of | ||
800 | * interlaced field formats | ||
801 | */ | ||
802 | __u32 il_vsync; /* Vertical sync length for bottom field of | ||
803 | * interlaced field formats | ||
804 | */ | ||
805 | __u32 il_vbackporch; /* Vertical back porch for bottom field of | ||
806 | * interlaced field formats | ||
807 | */ | ||
808 | __u32 reserved[16]; | ||
809 | } __attribute__ ((packed)); | ||
810 | |||
811 | /* Interlaced or progressive format */ | ||
812 | #define V4L2_DV_PROGRESSIVE 0 | ||
813 | #define V4L2_DV_INTERLACED 1 | ||
814 | |||
815 | /* Polarities. If bit is not set, it is assumed to be negative polarity */ | ||
816 | #define V4L2_DV_VSYNC_POS_POL 0x00000001 | ||
817 | #define V4L2_DV_HSYNC_POS_POL 0x00000002 | ||
818 | |||
819 | |||
820 | /* DV timings */ | ||
821 | struct v4l2_dv_timings { | ||
822 | __u32 type; | ||
823 | union { | ||
824 | struct v4l2_bt_timings bt; | ||
825 | __u32 reserved[32]; | ||
826 | }; | ||
827 | } __attribute__ ((packed)); | ||
828 | |||
829 | /* Values for the type field */ | ||
830 | #define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ | ||
831 | |||
832 | /* | ||
735 | * V I D E O I N P U T S | 833 | * V I D E O I N P U T S |
736 | */ | 834 | */ |
737 | struct v4l2_input { | 835 | struct v4l2_input { |
@@ -742,7 +840,8 @@ struct v4l2_input { | |||
742 | __u32 tuner; /* Associated tuner */ | 840 | __u32 tuner; /* Associated tuner */ |
743 | v4l2_std_id std; | 841 | v4l2_std_id std; |
744 | __u32 status; | 842 | __u32 status; |
745 | __u32 reserved[4]; | 843 | __u32 capabilities; |
844 | __u32 reserved[3]; | ||
746 | }; | 845 | }; |
747 | 846 | ||
748 | /* Values for the 'type' field */ | 847 | /* Values for the 'type' field */ |
@@ -773,6 +872,11 @@ struct v4l2_input { | |||
773 | #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ | 872 | #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ |
774 | #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ | 873 | #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ |
775 | 874 | ||
875 | /* capabilities flags */ | ||
876 | #define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ | ||
877 | #define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ | ||
878 | #define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ | ||
879 | |||
776 | /* | 880 | /* |
777 | * V I D E O O U T P U T S | 881 | * V I D E O O U T P U T S |
778 | */ | 882 | */ |
@@ -783,13 +887,19 @@ struct v4l2_output { | |||
783 | __u32 audioset; /* Associated audios (bitfield) */ | 887 | __u32 audioset; /* Associated audios (bitfield) */ |
784 | __u32 modulator; /* Associated modulator */ | 888 | __u32 modulator; /* Associated modulator */ |
785 | v4l2_std_id std; | 889 | v4l2_std_id std; |
786 | __u32 reserved[4]; | 890 | __u32 capabilities; |
891 | __u32 reserved[3]; | ||
787 | }; | 892 | }; |
788 | /* Values for the 'type' field */ | 893 | /* Values for the 'type' field */ |
789 | #define V4L2_OUTPUT_TYPE_MODULATOR 1 | 894 | #define V4L2_OUTPUT_TYPE_MODULATOR 1 |
790 | #define V4L2_OUTPUT_TYPE_ANALOG 2 | 895 | #define V4L2_OUTPUT_TYPE_ANALOG 2 |
791 | #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 | 896 | #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 |
792 | 897 | ||
898 | /* capabilities flags */ | ||
899 | #define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ | ||
900 | #define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ | ||
901 | #define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ | ||
902 | |||
793 | /* | 903 | /* |
794 | * C O N T R O L S | 904 | * C O N T R O L S |
795 | */ | 905 | */ |
@@ -1624,6 +1734,13 @@ struct v4l2_dbg_chip_ident { | |||
1624 | #endif | 1734 | #endif |
1625 | 1735 | ||
1626 | #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) | 1736 | #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) |
1737 | #define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset) | ||
1738 | #define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) | ||
1739 | #define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) | ||
1740 | #define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) | ||
1741 | #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) | ||
1742 | #define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) | ||
1743 | |||
1627 | /* Reminder: when adding new ioctls please add support for them to | 1744 | /* Reminder: when adding new ioctls please add support for them to |
1628 | drivers/media/video/v4l2-compat-ioctl32.c as well! */ | 1745 | drivers/media/video/v4l2-compat-ioctl32.c as well! */ |
1629 | 1746 | ||
diff --git a/include/media/ir-common.h b/include/media/ir-common.h index e41a99ee353..2c6af24b905 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h | |||
@@ -26,26 +26,7 @@ | |||
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/workqueue.h> | 27 | #include <linux/workqueue.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/spinlock.h> | 29 | #include <media/ir-core.h> |
30 | |||
31 | extern int media_ir_debug; /* media_ir_debug level (0,1,2) */ | ||
32 | #define IR_dprintk(level, fmt, arg...) if (media_ir_debug >= level) \ | ||
33 | printk(KERN_DEBUG "%s: " fmt , __func__, ## arg) | ||
34 | |||
35 | #define IR_TYPE_RC5 1 | ||
36 | #define IR_TYPE_PD 2 /* Pulse distance encoded IR */ | ||
37 | #define IR_TYPE_OTHER 99 | ||
38 | |||
39 | struct ir_scancode { | ||
40 | u16 scancode; | ||
41 | u32 keycode; | ||
42 | }; | ||
43 | |||
44 | struct ir_scancode_table { | ||
45 | struct ir_scancode *scan; | ||
46 | int size; | ||
47 | spinlock_t lock; | ||
48 | }; | ||
49 | 30 | ||
50 | #define RC5_START(x) (((x)>>12)&3) | 31 | #define RC5_START(x) (((x)>>12)&3) |
51 | #define RC5_TOGGLE(x) (((x)>>11)&1) | 32 | #define RC5_TOGGLE(x) (((x)>>11)&1) |
@@ -56,8 +37,6 @@ struct ir_input_state { | |||
56 | /* configuration */ | 37 | /* configuration */ |
57 | int ir_type; | 38 | int ir_type; |
58 | 39 | ||
59 | struct ir_scancode_table keytable; | ||
60 | |||
61 | /* key info */ | 40 | /* key info */ |
62 | u32 ir_key; /* ir scancode */ | 41 | u32 ir_key; /* ir scancode */ |
63 | u32 keycode; /* linux key code */ | 42 | u32 keycode; /* linux key code */ |
@@ -105,7 +84,7 @@ struct card_ir { | |||
105 | /* Routines from ir-functions.c */ | 84 | /* Routines from ir-functions.c */ |
106 | 85 | ||
107 | int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | 86 | int ir_input_init(struct input_dev *dev, struct ir_input_state *ir, |
108 | int ir_type, struct ir_scancode_table *ir_codes); | 87 | int ir_type); |
109 | void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); | 88 | void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir); |
110 | void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, | 89 | void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, |
111 | u32 ir_key); | 90 | u32 ir_key); |
@@ -118,19 +97,6 @@ u32 ir_rc5_decode(unsigned int code); | |||
118 | void ir_rc5_timer_end(unsigned long data); | 97 | void ir_rc5_timer_end(unsigned long data); |
119 | void ir_rc5_timer_keyup(unsigned long data); | 98 | void ir_rc5_timer_keyup(unsigned long data); |
120 | 99 | ||
121 | /* Routines from ir-keytable.c */ | ||
122 | |||
123 | u32 ir_g_keycode_from_table(struct input_dev *input_dev, | ||
124 | u32 scancode); | ||
125 | |||
126 | int ir_set_keycode_table(struct input_dev *input_dev, | ||
127 | struct ir_scancode_table *rc_tab); | ||
128 | |||
129 | int ir_roundup_tablesize(int n_elems); | ||
130 | int ir_copy_table(struct ir_scancode_table *destin, | ||
131 | const struct ir_scancode_table *origin); | ||
132 | void ir_input_free(struct input_dev *input_dev); | ||
133 | |||
134 | /* scancode->keycode map tables from ir-keymaps.c */ | 100 | /* scancode->keycode map tables from ir-keymaps.c */ |
135 | 101 | ||
136 | extern struct ir_scancode_table ir_codes_empty_table; | 102 | extern struct ir_scancode_table ir_codes_empty_table; |
@@ -195,4 +161,5 @@ extern struct ir_scancode_table ir_codes_evga_indtube_table; | |||
195 | extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table; | 161 | extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table; |
196 | extern struct ir_scancode_table ir_codes_videomate_s350_table; | 162 | extern struct ir_scancode_table ir_codes_videomate_s350_table; |
197 | extern struct ir_scancode_table ir_codes_gadmei_rm008z_table; | 163 | extern struct ir_scancode_table ir_codes_gadmei_rm008z_table; |
164 | extern struct ir_scancode_table ir_codes_nec_terratec_cinergy_xs_table; | ||
198 | #endif | 165 | #endif |
diff --git a/include/media/ir-core.h b/include/media/ir-core.h new file mode 100644 index 00000000000..299d201e133 --- /dev/null +++ b/include/media/ir-core.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Remote Controller core header | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation version 2 of the License. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef _IR_CORE | ||
15 | #define _IR_CORE | ||
16 | |||
17 | #include <linux/input.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | |||
20 | extern int ir_core_debug; | ||
21 | #define IR_dprintk(level, fmt, arg...) if (ir_core_debug >= level) \ | ||
22 | printk(KERN_DEBUG "%s: " fmt , __func__, ## arg) | ||
23 | |||
24 | enum ir_type { | ||
25 | IR_TYPE_UNKNOWN = 0, | ||
26 | IR_TYPE_RC5 = 1, | ||
27 | IR_TYPE_PD = 2, /* Pulse distance encoded IR */ | ||
28 | IR_TYPE_NEC = 3, | ||
29 | IR_TYPE_OTHER = 99, | ||
30 | }; | ||
31 | |||
32 | struct ir_scancode { | ||
33 | u16 scancode; | ||
34 | u32 keycode; | ||
35 | }; | ||
36 | |||
37 | struct ir_scancode_table { | ||
38 | struct ir_scancode *scan; | ||
39 | int size; | ||
40 | enum ir_type ir_type; | ||
41 | spinlock_t lock; | ||
42 | }; | ||
43 | |||
44 | struct ir_input_dev { | ||
45 | struct input_dev *dev; | ||
46 | struct ir_scancode_table rc_tab; | ||
47 | }; | ||
48 | |||
49 | /* Routines from ir-keytable.c */ | ||
50 | |||
51 | u32 ir_g_keycode_from_table(struct input_dev *input_dev, | ||
52 | u32 scancode); | ||
53 | |||
54 | int ir_set_keycode_table(struct input_dev *input_dev, | ||
55 | struct ir_scancode_table *rc_tab); | ||
56 | |||
57 | int ir_roundup_tablesize(int n_elems); | ||
58 | int ir_input_register(struct input_dev *dev, | ||
59 | struct ir_scancode_table *ir_codes); | ||
60 | void ir_input_unregister(struct input_dev *input_dev); | ||
61 | |||
62 | #endif | ||
diff --git a/include/media/mt9t112.h b/include/media/mt9t112.h new file mode 100644 index 00000000000..a43c74ab05e --- /dev/null +++ b/include/media/mt9t112.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* mt9t112 Camera | ||
2 | * | ||
3 | * Copyright (C) 2009 Renesas Solutions Corp. | ||
4 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __MT9T112_H__ | ||
12 | #define __MT9T112_H__ | ||
13 | |||
14 | #define MT9T112_FLAG_PCLK_RISING_EDGE (1 << 0) | ||
15 | #define MT9T112_FLAG_DATAWIDTH_8 (1 << 1) /* default width is 10 */ | ||
16 | |||
17 | struct mt9t112_pll_divider { | ||
18 | u8 m, n; | ||
19 | u8 p1, p2, p3, p4, p5, p6, p7; | ||
20 | }; | ||
21 | |||
22 | /* | ||
23 | * mt9t112 camera info | ||
24 | */ | ||
25 | struct mt9t112_camera_info { | ||
26 | u32 flags; | ||
27 | struct mt9t112_pll_divider divider; | ||
28 | }; | ||
29 | |||
30 | #endif /* __MT9T112_H__ */ | ||
diff --git a/include/media/ov772x.h b/include/media/ov772x.h index 30d9629198e..14c77efd6a8 100644 --- a/include/media/ov772x.h +++ b/include/media/ov772x.h | |||
@@ -1,4 +1,5 @@ | |||
1 | /* ov772x Camera | 1 | /* |
2 | * ov772x Camera | ||
2 | * | 3 | * |
3 | * Copyright (C) 2008 Renesas Solutions Corp. | 4 | * Copyright (C) 2008 Renesas Solutions Corp. |
4 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | 5 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> |
@@ -54,7 +55,6 @@ struct ov772x_edge_ctrl { | |||
54 | struct ov772x_camera_info { | 55 | struct ov772x_camera_info { |
55 | unsigned long buswidth; | 56 | unsigned long buswidth; |
56 | unsigned long flags; | 57 | unsigned long flags; |
57 | struct soc_camera_link link; | ||
58 | struct ov772x_edge_ctrl edgectrl; | 58 | struct ov772x_edge_ctrl edgectrl; |
59 | }; | 59 | }; |
60 | 60 | ||
diff --git a/include/media/rj54n1cb0c.h b/include/media/rj54n1cb0c.h new file mode 100644 index 00000000000..8ae3288ae92 --- /dev/null +++ b/include/media/rj54n1cb0c.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * RJ54N1CB0C Private data | ||
3 | * | ||
4 | * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __RJ54N1CB0C_H__ | ||
12 | #define __RJ54N1CB0C_H__ | ||
13 | |||
14 | struct rj54n1_pdata { | ||
15 | unsigned int mclk_freq; | ||
16 | bool ioctl_high; | ||
17 | }; | ||
18 | |||
19 | #endif | ||
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h index eed5fccc83f..4aeff96ff7d 100644 --- a/include/media/saa7146_vv.h +++ b/include/media/saa7146_vv.h | |||
@@ -108,8 +108,6 @@ struct saa7146_fh { | |||
108 | 108 | ||
109 | struct saa7146_vv | 109 | struct saa7146_vv |
110 | { | 110 | { |
111 | int vbi_minor; | ||
112 | |||
113 | /* vbi capture */ | 111 | /* vbi capture */ |
114 | struct saa7146_dmaqueue vbi_q; | 112 | struct saa7146_dmaqueue vbi_q; |
115 | /* vbi workaround interrupt queue */ | 113 | /* vbi workaround interrupt queue */ |
@@ -117,8 +115,6 @@ struct saa7146_vv | |||
117 | int vbi_fieldcount; | 115 | int vbi_fieldcount; |
118 | struct saa7146_fh *vbi_streaming; | 116 | struct saa7146_fh *vbi_streaming; |
119 | 117 | ||
120 | int video_minor; | ||
121 | |||
122 | int video_status; | 118 | int video_status; |
123 | struct saa7146_fh *video_fh; | 119 | struct saa7146_fh *video_fh; |
124 | 120 | ||
diff --git a/include/media/sh_mobile_ceu.h b/include/media/sh_mobile_ceu.h index 0f3524cff43..b6774783687 100644 --- a/include/media/sh_mobile_ceu.h +++ b/include/media/sh_mobile_ceu.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #define SH_CEU_FLAG_USE_8BIT_BUS (1 << 0) /* use 8bit bus width */ | 4 | #define SH_CEU_FLAG_USE_8BIT_BUS (1 << 0) /* use 8bit bus width */ |
5 | #define SH_CEU_FLAG_USE_16BIT_BUS (1 << 1) /* use 16bit bus width */ | 5 | #define SH_CEU_FLAG_USE_16BIT_BUS (1 << 1) /* use 16bit bus width */ |
6 | #define SH_CEU_FLAG_HSYNC_LOW (1 << 2) /* default High if possible */ | ||
7 | #define SH_CEU_FLAG_VSYNC_LOW (1 << 3) /* default High if possible */ | ||
6 | 8 | ||
7 | struct sh_mobile_ceu_info { | 9 | struct sh_mobile_ceu_info { |
8 | unsigned long flags; | 10 | unsigned long flags; |
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 3d74e60032d..dcc5b86bcb6 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h | |||
@@ -24,18 +24,13 @@ struct soc_camera_device { | |||
24 | struct device *pdev; /* Platform device */ | 24 | struct device *pdev; /* Platform device */ |
25 | s32 user_width; | 25 | s32 user_width; |
26 | s32 user_height; | 26 | s32 user_height; |
27 | unsigned short width_min; | 27 | enum v4l2_colorspace colorspace; |
28 | unsigned short height_min; | ||
29 | unsigned short y_skip_top; /* Lines to skip at the top */ | ||
30 | unsigned char iface; /* Host number */ | 28 | unsigned char iface; /* Host number */ |
31 | unsigned char devnum; /* Device number per host */ | 29 | unsigned char devnum; /* Device number per host */ |
32 | unsigned char buswidth; /* See comment in .c */ | ||
33 | struct soc_camera_sense *sense; /* See comment in struct definition */ | 30 | struct soc_camera_sense *sense; /* See comment in struct definition */ |
34 | struct soc_camera_ops *ops; | 31 | struct soc_camera_ops *ops; |
35 | struct video_device *vdev; | 32 | struct video_device *vdev; |
36 | const struct soc_camera_data_format *current_fmt; | 33 | const struct soc_camera_format_xlate *current_fmt; |
37 | const struct soc_camera_data_format *formats; | ||
38 | int num_formats; | ||
39 | struct soc_camera_format_xlate *user_formats; | 34 | struct soc_camera_format_xlate *user_formats; |
40 | int num_user_formats; | 35 | int num_user_formats; |
41 | enum v4l2_field field; /* Preserve field over close() */ | 36 | enum v4l2_field field; /* Preserve field over close() */ |
@@ -107,6 +102,8 @@ struct soc_camera_link { | |||
107 | int i2c_adapter_id; | 102 | int i2c_adapter_id; |
108 | struct i2c_board_info *board_info; | 103 | struct i2c_board_info *board_info; |
109 | const char *module_name; | 104 | const char *module_name; |
105 | void *priv; | ||
106 | |||
110 | /* | 107 | /* |
111 | * For non-I2C devices platform platform has to provide methods to | 108 | * For non-I2C devices platform platform has to provide methods to |
112 | * add a device to the system and to remove | 109 | * add a device to the system and to remove |
@@ -162,23 +159,13 @@ static inline struct v4l2_subdev *soc_camera_to_subdev( | |||
162 | int soc_camera_host_register(struct soc_camera_host *ici); | 159 | int soc_camera_host_register(struct soc_camera_host *ici); |
163 | void soc_camera_host_unregister(struct soc_camera_host *ici); | 160 | void soc_camera_host_unregister(struct soc_camera_host *ici); |
164 | 161 | ||
165 | const struct soc_camera_data_format *soc_camera_format_by_fourcc( | ||
166 | struct soc_camera_device *icd, unsigned int fourcc); | ||
167 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( | 162 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( |
168 | struct soc_camera_device *icd, unsigned int fourcc); | 163 | struct soc_camera_device *icd, unsigned int fourcc); |
169 | 164 | ||
170 | struct soc_camera_data_format { | ||
171 | const char *name; | ||
172 | unsigned int depth; | ||
173 | __u32 fourcc; | ||
174 | enum v4l2_colorspace colorspace; | ||
175 | }; | ||
176 | |||
177 | /** | 165 | /** |
178 | * struct soc_camera_format_xlate - match between host and sensor formats | 166 | * struct soc_camera_format_xlate - match between host and sensor formats |
179 | * @cam_fmt: sensor format provided by the sensor | 167 | * @code: code of a sensor provided format |
180 | * @host_fmt: host format after host translation from cam_fmt | 168 | * @host_fmt: host format after host translation from code |
181 | * @buswidth: bus width for this format | ||
182 | * | 169 | * |
183 | * Host and sensor translation structure. Used in table of host and sensor | 170 | * Host and sensor translation structure. Used in table of host and sensor |
184 | * formats matchings in soc_camera_device. A host can override the generic list | 171 | * formats matchings in soc_camera_device. A host can override the generic list |
@@ -186,9 +173,8 @@ struct soc_camera_data_format { | |||
186 | * format setup. | 173 | * format setup. |
187 | */ | 174 | */ |
188 | struct soc_camera_format_xlate { | 175 | struct soc_camera_format_xlate { |
189 | const struct soc_camera_data_format *cam_fmt; | 176 | enum v4l2_mbus_pixelcode code; |
190 | const struct soc_camera_data_format *host_fmt; | 177 | const struct soc_mbus_pixelfmt *host_fmt; |
191 | unsigned char buswidth; | ||
192 | }; | 178 | }; |
193 | 179 | ||
194 | struct soc_camera_ops { | 180 | struct soc_camera_ops { |
diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h index bb70401b814..0ecefe227b7 100644 --- a/include/media/soc_camera_platform.h +++ b/include/media/soc_camera_platform.h | |||
@@ -19,11 +19,10 @@ struct device; | |||
19 | struct soc_camera_platform_info { | 19 | struct soc_camera_platform_info { |
20 | const char *format_name; | 20 | const char *format_name; |
21 | unsigned long format_depth; | 21 | unsigned long format_depth; |
22 | struct v4l2_pix_format format; | 22 | struct v4l2_mbus_framefmt format; |
23 | unsigned long bus_param; | 23 | unsigned long bus_param; |
24 | struct device *dev; | 24 | struct device *dev; |
25 | int (*set_capture)(struct soc_camera_platform_info *info, int enable); | 25 | int (*set_capture)(struct soc_camera_platform_info *info, int enable); |
26 | struct soc_camera_link link; | ||
27 | }; | 26 | }; |
28 | 27 | ||
29 | #endif /* __SOC_CAMERA_H__ */ | 28 | #endif /* __SOC_CAMERA_H__ */ |
diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h new file mode 100644 index 00000000000..037cd7be001 --- /dev/null +++ b/include/media/soc_mediabus.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * SoC-camera Media Bus API extensions | ||
3 | * | ||
4 | * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef SOC_MEDIABUS_H | ||
12 | #define SOC_MEDIABUS_H | ||
13 | |||
14 | #include <linux/videodev2.h> | ||
15 | |||
16 | #include <media/v4l2-mediabus.h> | ||
17 | |||
18 | /** | ||
19 | * enum soc_mbus_packing - data packing types on the media-bus | ||
20 | * @SOC_MBUS_PACKING_NONE: no packing, bit-for-bit transfer to RAM | ||
21 | * @SOC_MBUS_PACKING_2X8_PADHI: 16 bits transferred in 2 8-bit samples, in the | ||
22 | * possibly incomplete byte high bits are padding | ||
23 | * @SOC_MBUS_PACKING_2X8_PADLO: as above, but low bits are padding | ||
24 | * @SOC_MBUS_PACKING_EXTEND16: sample width (e.g., 10 bits) has to be extended | ||
25 | * to 16 bits | ||
26 | */ | ||
27 | enum soc_mbus_packing { | ||
28 | SOC_MBUS_PACKING_NONE, | ||
29 | SOC_MBUS_PACKING_2X8_PADHI, | ||
30 | SOC_MBUS_PACKING_2X8_PADLO, | ||
31 | SOC_MBUS_PACKING_EXTEND16, | ||
32 | }; | ||
33 | |||
34 | /** | ||
35 | * enum soc_mbus_order - sample order on the media bus | ||
36 | * @SOC_MBUS_ORDER_LE: least significant sample first | ||
37 | * @SOC_MBUS_ORDER_BE: most significant sample first | ||
38 | */ | ||
39 | enum soc_mbus_order { | ||
40 | SOC_MBUS_ORDER_LE, | ||
41 | SOC_MBUS_ORDER_BE, | ||
42 | }; | ||
43 | |||
44 | /** | ||
45 | * struct soc_mbus_pixelfmt - Data format on the media bus | ||
46 | * @name: Name of the format | ||
47 | * @fourcc: Fourcc code, that will be obtained if the data is | ||
48 | * stored in memory in the following way: | ||
49 | * @packing: Type of sample-packing, that has to be used | ||
50 | * @order: Sample order when storing in memory | ||
51 | * @bits_per_sample: How many bits the bridge has to sample | ||
52 | */ | ||
53 | struct soc_mbus_pixelfmt { | ||
54 | const char *name; | ||
55 | u32 fourcc; | ||
56 | enum soc_mbus_packing packing; | ||
57 | enum soc_mbus_order order; | ||
58 | u8 bits_per_sample; | ||
59 | }; | ||
60 | |||
61 | const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( | ||
62 | enum v4l2_mbus_pixelcode code); | ||
63 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf); | ||
64 | |||
65 | #endif | ||
diff --git a/include/media/tw9910.h b/include/media/tw9910.h index 73231e7880d..5e2895a05e6 100644 --- a/include/media/tw9910.h +++ b/include/media/tw9910.h | |||
@@ -32,7 +32,6 @@ enum tw9910_mpout_pin { | |||
32 | struct tw9910_video_info { | 32 | struct tw9910_video_info { |
33 | unsigned long buswidth; | 33 | unsigned long buswidth; |
34 | enum tw9910_mpout_pin mpout; | 34 | enum tw9910_mpout_pin mpout; |
35 | struct soc_camera_link link; | ||
36 | }; | 35 | }; |
37 | 36 | ||
38 | 37 | ||
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 91942dbe64e..6cc107d198a 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h | |||
@@ -267,6 +267,8 @@ enum { | |||
267 | V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ | 267 | V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ |
268 | V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ | 268 | V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ |
269 | V4L2_IDENT_MT9T031 = 45020, | 269 | V4L2_IDENT_MT9T031 = 45020, |
270 | V4L2_IDENT_MT9T111 = 45021, | ||
271 | V4L2_IDENT_MT9T112 = 45022, | ||
270 | V4L2_IDENT_MT9V111 = 45031, | 272 | V4L2_IDENT_MT9V111 = 45031, |
271 | V4L2_IDENT_MT9V112 = 45032, | 273 | V4L2_IDENT_MT9V112 = 45032, |
272 | 274 | ||
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 1c25b10da34..1c7b259f341 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h | |||
@@ -212,5 +212,5 @@ void v4l_bound_align_image(unsigned int *w, unsigned int wmin, | |||
212 | unsigned int *h, unsigned int hmin, | 212 | unsigned int *h, unsigned int hmin, |
213 | unsigned int hmax, unsigned int halign, | 213 | unsigned int hmax, unsigned int halign, |
214 | unsigned int salign); | 214 | unsigned int salign); |
215 | 215 | int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info); | |
216 | #endif /* V4L2_COMMON_H_ */ | 216 | #endif /* V4L2_COMMON_H_ */ |
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 73c9867d744..2dee93892ea 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h | |||
@@ -28,10 +28,10 @@ struct v4l2_ioctl_callbacks; | |||
28 | struct video_device; | 28 | struct video_device; |
29 | struct v4l2_device; | 29 | struct v4l2_device; |
30 | 30 | ||
31 | /* Flag to mark the video_device struct as unregistered. | 31 | /* Flag to mark the video_device struct as registered. |
32 | Drivers can set this flag if they want to block all future | 32 | Drivers can clear this flag if they want to block all future |
33 | device access. It is set by video_unregister_device. */ | 33 | device access. It is cleared by video_unregister_device. */ |
34 | #define V4L2_FL_UNREGISTERED (0) | 34 | #define V4L2_FL_REGISTERED (0) |
35 | 35 | ||
36 | struct v4l2_file_operations { | 36 | struct v4l2_file_operations { |
37 | struct module *owner; | 37 | struct module *owner; |
@@ -96,9 +96,7 @@ struct video_device | |||
96 | /* Register video devices. Note that if video_register_device fails, | 96 | /* Register video devices. Note that if video_register_device fails, |
97 | the release() callback of the video_device structure is *not* called, so | 97 | the release() callback of the video_device structure is *not* called, so |
98 | the caller is responsible for freeing any data. Usually that means that | 98 | the caller is responsible for freeing any data. Usually that means that |
99 | you call video_device_release() on failure. | 99 | you call video_device_release() on failure. */ |
100 | |||
101 | Also note that vdev->minor is set to -1 if the registration failed. */ | ||
102 | int __must_check video_register_device(struct video_device *vdev, int type, int nr); | 100 | int __must_check video_register_device(struct video_device *vdev, int type, int nr); |
103 | 101 | ||
104 | /* Same as video_register_device, but no warning is issued if the desired | 102 | /* Same as video_register_device, but no warning is issued if the desired |
@@ -106,7 +104,7 @@ int __must_check video_register_device(struct video_device *vdev, int type, int | |||
106 | int __must_check video_register_device_no_warn(struct video_device *vdev, int type, int nr); | 104 | int __must_check video_register_device_no_warn(struct video_device *vdev, int type, int nr); |
107 | 105 | ||
108 | /* Unregister video devices. Will do nothing if vdev == NULL or | 106 | /* Unregister video devices. Will do nothing if vdev == NULL or |
109 | vdev->minor < 0. */ | 107 | video_is_registered() returns false. */ |
110 | void video_unregister_device(struct video_device *vdev); | 108 | void video_unregister_device(struct video_device *vdev); |
111 | 109 | ||
112 | /* helper functions to alloc/release struct video_device, the | 110 | /* helper functions to alloc/release struct video_device, the |
@@ -141,9 +139,14 @@ static inline void *video_drvdata(struct file *file) | |||
141 | return video_get_drvdata(video_devdata(file)); | 139 | return video_get_drvdata(video_devdata(file)); |
142 | } | 140 | } |
143 | 141 | ||
144 | static inline int video_is_unregistered(struct video_device *vdev) | 142 | static inline const char *video_device_node_name(struct video_device *vdev) |
143 | { | ||
144 | return dev_name(&vdev->dev); | ||
145 | } | ||
146 | |||
147 | static inline int video_is_registered(struct video_device *vdev) | ||
145 | { | 148 | { |
146 | return test_bit(V4L2_FL_UNREGISTERED, &vdev->flags); | 149 | return test_bit(V4L2_FL_REGISTERED, &vdev->flags); |
147 | } | 150 | } |
148 | 151 | ||
149 | #endif /* _V4L2_DEV_H */ | 152 | #endif /* _V4L2_DEV_H */ |
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 7a4529defa8..e8ba0f2efba 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h | |||
@@ -239,6 +239,21 @@ struct v4l2_ioctl_ops { | |||
239 | int (*vidioc_enum_frameintervals) (struct file *file, void *fh, | 239 | int (*vidioc_enum_frameintervals) (struct file *file, void *fh, |
240 | struct v4l2_frmivalenum *fival); | 240 | struct v4l2_frmivalenum *fival); |
241 | 241 | ||
242 | /* DV Timings IOCTLs */ | ||
243 | int (*vidioc_enum_dv_presets) (struct file *file, void *fh, | ||
244 | struct v4l2_dv_enum_preset *preset); | ||
245 | |||
246 | int (*vidioc_s_dv_preset) (struct file *file, void *fh, | ||
247 | struct v4l2_dv_preset *preset); | ||
248 | int (*vidioc_g_dv_preset) (struct file *file, void *fh, | ||
249 | struct v4l2_dv_preset *preset); | ||
250 | int (*vidioc_query_dv_preset) (struct file *file, void *fh, | ||
251 | struct v4l2_dv_preset *qpreset); | ||
252 | int (*vidioc_s_dv_timings) (struct file *file, void *fh, | ||
253 | struct v4l2_dv_timings *timings); | ||
254 | int (*vidioc_g_dv_timings) (struct file *file, void *fh, | ||
255 | struct v4l2_dv_timings *timings); | ||
256 | |||
242 | /* For other private ioctls */ | 257 | /* For other private ioctls */ |
243 | long (*vidioc_default) (struct file *file, void *fh, | 258 | long (*vidioc_default) (struct file *file, void *fh, |
244 | int cmd, void *arg); | 259 | int cmd, void *arg); |
diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h new file mode 100644 index 00000000000..0dbe02ada25 --- /dev/null +++ b/include/media/v4l2-mediabus.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Media Bus API header | ||
3 | * | ||
4 | * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef V4L2_MEDIABUS_H | ||
12 | #define V4L2_MEDIABUS_H | ||
13 | |||
14 | /* | ||
15 | * These pixel codes uniquely identify data formats on the media bus. Mostly | ||
16 | * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is | ||
17 | * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the | ||
18 | * data format is fixed. Additionally, "2X8" means that one pixel is transferred | ||
19 | * in two 8-bit samples, "BE" or "LE" specify in which order those samples are | ||
20 | * transferred over the bus: "LE" means that the least significant bits are | ||
21 | * transferred first, "BE" means that the most significant bits are transferred | ||
22 | * first, and "PADHI" and "PADLO" define which bits - low or high, in the | ||
23 | * incomplete high byte, are filled with padding bits. | ||
24 | */ | ||
25 | enum v4l2_mbus_pixelcode { | ||
26 | V4L2_MBUS_FMT_FIXED = 1, | ||
27 | V4L2_MBUS_FMT_YUYV8_2X8_LE, | ||
28 | V4L2_MBUS_FMT_YVYU8_2X8_LE, | ||
29 | V4L2_MBUS_FMT_YUYV8_2X8_BE, | ||
30 | V4L2_MBUS_FMT_YVYU8_2X8_BE, | ||
31 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, | ||
32 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, | ||
33 | V4L2_MBUS_FMT_RGB565_2X8_LE, | ||
34 | V4L2_MBUS_FMT_RGB565_2X8_BE, | ||
35 | V4L2_MBUS_FMT_SBGGR8_1X8, | ||
36 | V4L2_MBUS_FMT_SBGGR10_1X10, | ||
37 | V4L2_MBUS_FMT_GREY8_1X8, | ||
38 | V4L2_MBUS_FMT_Y10_1X10, | ||
39 | V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, | ||
40 | V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, | ||
41 | V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, | ||
42 | V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, | ||
43 | }; | ||
44 | |||
45 | /** | ||
46 | * struct v4l2_mbus_framefmt - frame format on the media bus | ||
47 | * @width: frame width | ||
48 | * @height: frame height | ||
49 | * @code: data format code | ||
50 | * @field: used interlacing type | ||
51 | * @colorspace: colorspace of the data | ||
52 | */ | ||
53 | struct v4l2_mbus_framefmt { | ||
54 | __u32 width; | ||
55 | __u32 height; | ||
56 | enum v4l2_mbus_pixelcode code; | ||
57 | enum v4l2_field field; | ||
58 | enum v4l2_colorspace colorspace; | ||
59 | }; | ||
60 | |||
61 | #endif | ||
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 00bf1760845..9ba99cd39ee 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define _V4L2_SUBDEV_H | 22 | #define _V4L2_SUBDEV_H |
23 | 23 | ||
24 | #include <media/v4l2-common.h> | 24 | #include <media/v4l2-common.h> |
25 | #include <media/v4l2-mediabus.h> | ||
25 | 26 | ||
26 | /* generic v4l2_device notify callback notification values */ | 27 | /* generic v4l2_device notify callback notification values */ |
27 | #define V4L2_SUBDEV_IR_RX_NOTIFY _IOW('v', 0, u32) | 28 | #define V4L2_SUBDEV_IR_RX_NOTIFY _IOW('v', 0, u32) |
@@ -207,7 +208,7 @@ struct v4l2_subdev_audio_ops { | |||
207 | s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by | 208 | s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by |
208 | video input devices. | 209 | video input devices. |
209 | 210 | ||
210 | s_crystal_freq: sets the frequency of the crystal used to generate the | 211 | s_crystal_freq: sets the frequency of the crystal used to generate the |
211 | clocks in Hz. An extra flags field allows device specific configuration | 212 | clocks in Hz. An extra flags field allows device specific configuration |
212 | regarding clock frequency dividers, etc. If not used, then set flags | 213 | regarding clock frequency dividers, etc. If not used, then set flags |
213 | to 0. If the frequency is not supported, then -EINVAL is returned. | 214 | to 0. If the frequency is not supported, then -EINVAL is returned. |
@@ -217,6 +218,26 @@ struct v4l2_subdev_audio_ops { | |||
217 | 218 | ||
218 | s_routing: see s_routing in audio_ops, except this version is for video | 219 | s_routing: see s_routing in audio_ops, except this version is for video |
219 | devices. | 220 | devices. |
221 | |||
222 | s_dv_preset: set dv (Digital Video) preset in the sub device. Similar to | ||
223 | s_std() | ||
224 | |||
225 | query_dv_preset: query dv preset in the sub device. This is similar to | ||
226 | querystd() | ||
227 | |||
228 | s_dv_timings(): Set custom dv timings in the sub device. This is used | ||
229 | when sub device is capable of setting detailed timing information | ||
230 | in the hardware to generate/detect the video signal. | ||
231 | |||
232 | g_dv_timings(): Get custom dv timings in the sub device. | ||
233 | |||
234 | enum_mbus_fmt: enumerate pixel formats, provided by a video data source | ||
235 | |||
236 | g_mbus_fmt: get the current pixel format, provided by a video data source | ||
237 | |||
238 | try_mbus_fmt: try to set a pixel format on a video data source | ||
239 | |||
240 | s_mbus_fmt: set a pixel format on a video data source | ||
220 | */ | 241 | */ |
221 | struct v4l2_subdev_video_ops { | 242 | struct v4l2_subdev_video_ops { |
222 | int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); | 243 | int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); |
@@ -240,6 +261,33 @@ struct v4l2_subdev_video_ops { | |||
240 | int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); | 261 | int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); |
241 | int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); | 262 | int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); |
242 | int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); | 263 | int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); |
264 | int (*s_dv_preset)(struct v4l2_subdev *sd, | ||
265 | struct v4l2_dv_preset *preset); | ||
266 | int (*query_dv_preset)(struct v4l2_subdev *sd, | ||
267 | struct v4l2_dv_preset *preset); | ||
268 | int (*s_dv_timings)(struct v4l2_subdev *sd, | ||
269 | struct v4l2_dv_timings *timings); | ||
270 | int (*g_dv_timings)(struct v4l2_subdev *sd, | ||
271 | struct v4l2_dv_timings *timings); | ||
272 | int (*enum_mbus_fmt)(struct v4l2_subdev *sd, int index, | ||
273 | enum v4l2_mbus_pixelcode *code); | ||
274 | int (*g_mbus_fmt)(struct v4l2_subdev *sd, | ||
275 | struct v4l2_mbus_framefmt *fmt); | ||
276 | int (*try_mbus_fmt)(struct v4l2_subdev *sd, | ||
277 | struct v4l2_mbus_framefmt *fmt); | ||
278 | int (*s_mbus_fmt)(struct v4l2_subdev *sd, | ||
279 | struct v4l2_mbus_framefmt *fmt); | ||
280 | }; | ||
281 | |||
282 | /** | ||
283 | * struct v4l2_subdev_sensor_ops - v4l2-subdev sensor operations | ||
284 | * @g_skip_top_lines: number of lines at the top of the image to be skipped. | ||
285 | * This is needed for some sensors, which always corrupt | ||
286 | * several top lines of the output image, or which send their | ||
287 | * metadata in them. | ||
288 | */ | ||
289 | struct v4l2_subdev_sensor_ops { | ||
290 | int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines); | ||
243 | }; | 291 | }; |
244 | 292 | ||
245 | /* | 293 | /* |
@@ -326,11 +374,12 @@ struct v4l2_subdev_ir_ops { | |||
326 | }; | 374 | }; |
327 | 375 | ||
328 | struct v4l2_subdev_ops { | 376 | struct v4l2_subdev_ops { |
329 | const struct v4l2_subdev_core_ops *core; | 377 | const struct v4l2_subdev_core_ops *core; |
330 | const struct v4l2_subdev_tuner_ops *tuner; | 378 | const struct v4l2_subdev_tuner_ops *tuner; |
331 | const struct v4l2_subdev_audio_ops *audio; | 379 | const struct v4l2_subdev_audio_ops *audio; |
332 | const struct v4l2_subdev_video_ops *video; | 380 | const struct v4l2_subdev_video_ops *video; |
333 | const struct v4l2_subdev_ir_ops *ir; | 381 | const struct v4l2_subdev_ir_ops *ir; |
382 | const struct v4l2_subdev_sensor_ops *sensor; | ||
334 | }; | 383 | }; |
335 | 384 | ||
336 | #define V4L2_SUBDEV_NAME_SIZE 32 | 385 | #define V4L2_SUBDEV_NAME_SIZE 32 |