Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:
- V4L2 API additions to better support JPEG compression control
- media API additions to properly support MPEG decoders
- V4L2 API additions for image crop/scaling
- a few other V4L2 API DocBook fixes/improvements
- two new DVB frontend drivers: m88rs2000 and rtl2830
- two new DVB drivers: az6007 and rtl28xxu
- a framework for ISA drivers, that removed lots of common code found
at the ISA radio drivers
- a new FM transmitter driver (radio-keene)
- a GPIO-based IR receiver driver
- a new sensor driver: mt9m032
- some new video drivers: adv7183, blackfin, mx2_emmaprp, sii9234_drv,
vs6624
- several new board additions, driver fixes, improvements and cleanups.

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (295 commits)
[media] update CARDLIST.em28xx
[media] partially reverts changeset fa5527c
[media] stb0899: fix the limits for signal strength values
[media] em28xx: support for 2304:0242 PCTV QuatroStick (510e)
[media] em28xx: support for 2013:0251 PCTV QuatroStick nano (520e)
[media] -EINVAL -> -ENOTTY
[media] gspca - sn9c20x: Cleanup source
[media] gspca - sn9c20x: Simplify register write for capture start/stop
[media] gspca - sn9c20x: Add automatic JPEG compression mechanism
[media] gspca - sn9c20x: Greater delay in case of sensor no response
[media] gspca - sn9c20x: Optimize the code of write sequences
[media] gspca - sn9c20x: Add the JPEG compression quality control
[media] gspca - sn9c20x: Add a delay after Omnivision sensor reset
[media] gspca - sn9c20x: Propagate USB errors to higher level
[media] gspca - sn9c20x: Use the new video control mechanism
[media] gspca - sn9c20x: Fix loss of frame start
[media] gspca - zc3xx: Lack of register 08 value for sensor cs2102k
[media] gspca - ov534_9: Add brightness to OmniVision 5621 sensor
[media] gspca - zc3xx: Add V4L2_CID_JPEG_COMPRESSION_QUALITY control support
[media] pvrusb2: fix 7MHz & 8MHz DVB-T tuner support for HVR1900 rev D1F5
...

+18566 -7094
+20
Documentation/DocBook/media/v4l/biblio.xml
··· 128 128 <subtitle>Version 1.02</subtitle> 129 129 </biblioentry> 130 130 131 + <biblioentry id="itu-t81"> 132 + <abbrev>ITU-T.81</abbrev> 133 + <authorgroup> 134 + <corpauthor>International Telecommunication Union 135 + (<ulink url="http://www.itu.int">http://www.itu.int</ulink>)</corpauthor> 136 + </authorgroup> 137 + <title>ITU-T Recommendation T.81 138 + "Information Technology &mdash; Digital Compression and Coding of Continous-Tone 139 + Still Images &mdash; Requirements and Guidelines"</title> 140 + </biblioentry> 141 + 142 + <biblioentry id="w3c-jpeg-jfif"> 143 + <abbrev>W3C JPEG JFIF</abbrev> 144 + <authorgroup> 145 + <corpauthor>The World Wide Web Consortium (<ulink 146 + url="http://www.w3.org/Graphics/JPEG">http://www.w3.org</ulink>)</corpauthor> 147 + </authorgroup> 148 + <title>JPEG JFIF</title> 149 + </biblioentry> 150 + 131 151 <biblioentry id="smpte12m"> 132 152 <abbrev>SMPTE&nbsp;12M</abbrev> 133 153 <authorgroup>
+14
Documentation/DocBook/media/v4l/compat.xml
··· 2393 2393 to the <link linkend="control">User controls class</link>. 2394 2394 </para> 2395 2395 </listitem> 2396 + <listitem> 2397 + <para>Added the device_caps field to struct v4l2_capabilities and added the new 2398 + V4L2_CAP_DEVICE_CAPS capability.</para> 2399 + </listitem> 2400 + </orderedlist> 2401 + </section> 2402 + 2403 + <section> 2404 + <title>V4L2 in Linux 3.4</title> 2405 + <orderedlist> 2406 + <listitem> 2407 + <para>Added <link linkend="jpeg-controls">JPEG compression control 2408 + class</link>.</para> 2409 + </listitem> 2396 2410 </orderedlist> 2397 2411 </section> 2398 2412
+220
Documentation/DocBook/media/v4l/controls.xml
··· 1286 1286 and reproducible audio bitstream. 0 = unmuted, 1 = muted.</entry> 1287 1287 </row> 1288 1288 <row><entry></entry></row> 1289 + <row id="v4l2-mpeg-audio-dec-playback"> 1290 + <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK</constant>&nbsp;</entry> 1291 + <entry>enum&nbsp;v4l2_mpeg_audio_dec_playback</entry> 1292 + </row><row><entry spanname="descr">Determines how monolingual audio should be played back. 1293 + Possible values are:</entry> 1294 + </row> 1295 + <row> 1296 + <entrytbl spanname="descr" cols="2"> 1297 + <tbody valign="top"> 1298 + <row> 1299 + <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO</constant>&nbsp;</entry> 1300 + <entry>Automatically determines the best playback mode.</entry> 1301 + </row> 1302 + <row> 1303 + <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO</constant>&nbsp;</entry> 1304 + <entry>Stereo playback.</entry> 1305 + </row> 1306 + <row> 1307 + <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT</constant>&nbsp;</entry> 1308 + <entry>Left channel playback.</entry> 1309 + </row> 1310 + <row> 1311 + <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT</constant>&nbsp;</entry> 1312 + <entry>Right channel playback.</entry> 1313 + </row> 1314 + <row> 1315 + <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO</constant>&nbsp;</entry> 1316 + <entry>Mono playback.</entry> 1317 + </row> 1318 + <row> 1319 + <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO</constant>&nbsp;</entry> 1320 + <entry>Stereo playback with swapped left and right channels.</entry> 1321 + </row> 1322 + </tbody> 1323 + </entrytbl> 1324 + </row> 1325 + <row><entry></entry></row> 1326 + <row id="v4l2-mpeg-audio-dec-multilingual-playback"> 1327 + <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK</constant>&nbsp;</entry> 1328 + <entry>enum&nbsp;v4l2_mpeg_audio_dec_playback</entry> 1329 + </row><row><entry spanname="descr">Determines how multilingual audio should be played back.</entry> 1330 + </row> 1331 + <row><entry></entry></row> 1289 1332 <row id="v4l2-mpeg-video-encoding"> 1290 1333 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_ENCODING</constant>&nbsp;</entry> 1291 1334 <entry>enum&nbsp;v4l2_mpeg_video_encoding</entry> ··· 1489 1446 </row> 1490 1447 </tbody> 1491 1448 </entrytbl> 1449 + </row> 1450 + <row><entry></entry></row> 1451 + <row id="v4l2-mpeg-video-dec-pts"> 1452 + <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_DEC_PTS</constant>&nbsp;</entry> 1453 + <entry>integer64</entry> 1454 + </row><row><entry spanname="descr">This read-only control returns the 1455 + 33-bit video Presentation Time Stamp as defined in ITU T-REC-H.222.0 and ISO/IEC 13818-1 of 1456 + the currently displayed frame. This is the same PTS as is used in &VIDIOC-DECODER-CMD;.</entry> 1457 + </row> 1458 + <row><entry></entry></row> 1459 + <row id="v4l2-mpeg-video-dec-frame"> 1460 + <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_DEC_FRAME</constant>&nbsp;</entry> 1461 + <entry>integer64</entry> 1462 + </row><row><entry spanname="descr">This read-only control returns the 1463 + frame counter of the frame that is currently displayed (decoded). This value is reset to 0 whenever 1464 + the decoder is started.</entry> 1492 1465 </row> 1493 1466 1494 1467 ··· 3436 3377 </tbody> 3437 3378 </tgroup> 3438 3379 </table> 3380 + </section> 3439 3381 3382 + <section id="jpeg-controls"> 3383 + <title>JPEG Control Reference</title> 3384 + <para>The JPEG class includes controls for common features of JPEG 3385 + encoders and decoders. Currently it includes features for codecs 3386 + implementing progressive baseline DCT compression process with 3387 + Huffman entrophy coding.</para> 3388 + <table pgwide="1" frame="none" id="jpeg-control-id"> 3389 + <title>JPEG Control IDs</title> 3390 + 3391 + <tgroup cols="4"> 3392 + <colspec colname="c1" colwidth="1*" /> 3393 + <colspec colname="c2" colwidth="6*" /> 3394 + <colspec colname="c3" colwidth="2*" /> 3395 + <colspec colname="c4" colwidth="6*" /> 3396 + <spanspec namest="c1" nameend="c2" spanname="id" /> 3397 + <spanspec namest="c2" nameend="c4" spanname="descr" /> 3398 + <thead> 3399 + <row> 3400 + <entry spanname="id" align="left">ID</entry> 3401 + <entry align="left">Type</entry> 3402 + </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry> 3403 + </row> 3404 + </thead> 3405 + <tbody valign="top"> 3406 + <row><entry></entry></row> 3407 + <row> 3408 + <entry spanname="id"><constant>V4L2_CID_JPEG_CLASS</constant>&nbsp;</entry> 3409 + <entry>class</entry> 3410 + </row><row><entry spanname="descr">The JPEG class descriptor. Calling 3411 + &VIDIOC-QUERYCTRL; for this control will return a description of this 3412 + control class. 3413 + 3414 + </entry> 3415 + </row> 3416 + <row> 3417 + <entry spanname="id"><constant>V4L2_CID_JPEG_CHROMA_SUBSAMPLING</constant></entry> 3418 + <entry>menu</entry> 3419 + </row> 3420 + <row id="jpeg-chroma-subsampling-control"> 3421 + <entry spanname="descr">The chroma subsampling factors describe how 3422 + each component of an input image is sampled, in respect to maximum 3423 + sample rate in each spatial dimension. See <xref linkend="itu-t81"/>, 3424 + clause A.1.1. for more details. The <constant> 3425 + V4L2_CID_JPEG_CHROMA_SUBSAMPLING</constant> control determines how 3426 + Cb and Cr components are downsampled after coverting an input image 3427 + from RGB to Y'CbCr color space. 3428 + </entry> 3429 + </row> 3430 + <row> 3431 + <entrytbl spanname="descr" cols="2"> 3432 + <tbody valign="top"> 3433 + <row> 3434 + <entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_444</constant> 3435 + </entry><entry>No chroma subsampling, each pixel has 3436 + Y, Cr and Cb values.</entry> 3437 + </row> 3438 + <row> 3439 + <entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_422</constant> 3440 + </entry><entry>Horizontally subsample Cr, Cb components 3441 + by a factor of 2.</entry> 3442 + </row> 3443 + <row> 3444 + <entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_420</constant> 3445 + </entry><entry>Subsample Cr, Cb components horizontally 3446 + and vertically by 2.</entry> 3447 + </row> 3448 + <row> 3449 + <entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_411</constant> 3450 + </entry><entry>Horizontally subsample Cr, Cb components 3451 + by a factor of 4.</entry> 3452 + </row> 3453 + <row> 3454 + <entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_410</constant> 3455 + </entry><entry>Subsample Cr, Cb components horizontally 3456 + by 4 and vertically by 2.</entry> 3457 + </row> 3458 + <row> 3459 + <entry><constant>V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY</constant> 3460 + </entry><entry>Use only luminance component.</entry> 3461 + </row> 3462 + </tbody> 3463 + </entrytbl> 3464 + </row> 3465 + <row> 3466 + <entry spanname="id"><constant>V4L2_CID_JPEG_RESTART_INTERVAL</constant> 3467 + </entry><entry>integer</entry> 3468 + </row> 3469 + <row><entry spanname="descr"> 3470 + The restart interval determines an interval of inserting RSTm 3471 + markers (m = 0..7). The purpose of these markers is to additionally 3472 + reinitialize the encoder process, in order to process blocks of 3473 + an image independently. 3474 + For the lossy compression processes the restart interval unit is 3475 + MCU (Minimum Coded Unit) and its value is contained in DRI 3476 + (Define Restart Interval) marker. If <constant> 3477 + V4L2_CID_JPEG_RESTART_INTERVAL</constant> control is set to 0, 3478 + DRI and RSTm markers will not be inserted. 3479 + </entry> 3480 + </row> 3481 + <row id="jpeg-quality-control"> 3482 + <entry spanname="id"><constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant></entry> 3483 + <entry>integer</entry> 3484 + </row> 3485 + <row> 3486 + <entry spanname="descr"> 3487 + <constant>V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control 3488 + determines trade-off between image quality and size. 3489 + It provides simpler method for applications to control image quality, 3490 + without a need for direct reconfiguration of luminance and chrominance 3491 + quantization tables. 3492 + 3493 + In cases where a driver uses quantization tables configured directly 3494 + by an application, using interfaces defined elsewhere, <constant> 3495 + V4L2_CID_JPEG_COMPRESION_QUALITY</constant> control should be set 3496 + by driver to 0. 3497 + 3498 + <para>The value range of this control is driver-specific. Only 3499 + positive, non-zero values are meaningful. The recommended range 3500 + is 1 - 100, where larger values correspond to better image quality. 3501 + </para> 3502 + </entry> 3503 + </row> 3504 + <row id="jpeg-active-marker-control"> 3505 + <entry spanname="id"><constant>V4L2_CID_JPEG_ACTIVE_MARKER</constant></entry> 3506 + <entry>bitmask</entry> 3507 + </row> 3508 + <row> 3509 + <entry spanname="descr">Specify which JPEG markers are included 3510 + in compressed stream. This control is valid only for encoders. 3511 + </entry> 3512 + </row> 3513 + <row> 3514 + <entrytbl spanname="descr" cols="2"> 3515 + <tbody valign="top"> 3516 + <row> 3517 + <entry><constant>V4L2_JPEG_ACTIVE_MARKER_APP0</constant></entry> 3518 + <entry>Application data segment APP<subscript>0</subscript>.</entry> 3519 + </row><row> 3520 + <entry><constant>V4L2_JPEG_ACTIVE_MARKER_APP1</constant></entry> 3521 + <entry>Application data segment APP<subscript>1</subscript>.</entry> 3522 + </row><row> 3523 + <entry><constant>V4L2_JPEG_ACTIVE_MARKER_COM</constant></entry> 3524 + <entry>Comment segment.</entry> 3525 + </row><row> 3526 + <entry><constant>V4L2_JPEG_ACTIVE_MARKER_DQT</constant></entry> 3527 + <entry>Quantization tables segment.</entry> 3528 + </row><row> 3529 + <entry><constant>V4L2_JPEG_ACTIVE_MARKER_DHT</constant></entry> 3530 + <entry>Huffman tables segment.</entry> 3531 + </row> 3532 + </tbody> 3533 + </entrytbl> 3534 + </row> 3535 + <row><entry></entry></row> 3536 + </tbody> 3537 + </tgroup> 3538 + </table> 3539 + <para>For more details about JPEG specification, refer 3540 + to <xref linkend="itu-t81"/>, <xref linkend="jfif"/>, 3541 + <xref linkend="w3c-jpeg-jfif"/>.</para> 3440 3542 </section> 3441 3543 </section>
+6 -2
Documentation/DocBook/media/v4l/selection-api.xml
··· 52 52 </textobject> 53 53 </mediaobject> 54 54 </figure> 55 + 56 + For complete list of the available selection targets see table <xref 57 + linkend="v4l2-sel-target"/> 58 + 55 59 </section> 56 60 57 61 <section> ··· 190 186 191 187 <section> 192 188 193 - <title>Scaling control.</title> 189 + <title>Scaling control</title> 194 190 195 191 <para>An application can detect if scaling is performed by comparing the width 196 192 and the height of rectangles obtained using <constant> V4L2_SEL_TGT_CROP_ACTIVE ··· 204 200 205 201 <section> 206 202 207 - <title>Comparison with old cropping API.</title> 203 + <title>Comparison with old cropping API</title> 208 204 209 205 <para>The selection API was introduced to cope with deficiencies of previous 210 206 <link linkend="crop"> API </link>, that was designed to control simple capture
+18 -1
Documentation/DocBook/media/v4l/v4l2.xml
··· 128 128 applications. --> 129 129 130 130 <revision> 131 + <revnumber>3.4</revnumber> 132 + <date>2012-01-25</date> 133 + <authorinitials>sn</authorinitials> 134 + <revremark>Added <link linkend="jpeg-controls">JPEG compression 135 + control class.</link> 136 + </revremark> 137 + </revision> 138 + 139 + <revision> 140 + <revnumber>3.3</revnumber> 141 + <date>2012-01-11</date> 142 + <authorinitials>hv</authorinitials> 143 + <revremark>Added device_caps field to struct v4l2_capabilities.</revremark> 144 + </revision> 145 + 146 + <revision> 131 147 <revnumber>3.2</revnumber> 132 148 <date>2011-08-26</date> 133 149 <authorinitials>hv</authorinitials> ··· 433 417 </partinfo> 434 418 435 419 <title>Video for Linux Two API Specification</title> 436 - <subtitle>Revision 3.2</subtitle> 420 + <subtitle>Revision 3.3</subtitle> 437 421 438 422 <chapter id="common"> 439 423 &sub-common; ··· 489 473 &sub-cropcap; 490 474 &sub-dbg-g-chip-ident; 491 475 &sub-dbg-g-register; 476 + &sub-decoder-cmd; 492 477 &sub-dqevent; 493 478 &sub-encoder-cmd; 494 479 &sub-enumaudio;
+256
Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml
··· 1 + <refentry id="vidioc-decoder-cmd"> 2 + <refmeta> 3 + <refentrytitle>ioctl VIDIOC_DECODER_CMD, VIDIOC_TRY_DECODER_CMD</refentrytitle> 4 + &manvol; 5 + </refmeta> 6 + 7 + <refnamediv> 8 + <refname>VIDIOC_DECODER_CMD</refname> 9 + <refname>VIDIOC_TRY_DECODER_CMD</refname> 10 + <refpurpose>Execute an decoder command</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>struct v4l2_decoder_cmd *<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_DECODER_CMD, VIDIOC_TRY_DECODER_CMD</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 + <note> 53 + <title>Experimental</title> 54 + 55 + <para>This is an <link linkend="experimental">experimental</link> 56 + interface and may change in the future.</para> 57 + </note> 58 + 59 + <para>These ioctls control an audio/video (usually MPEG-) decoder. 60 + <constant>VIDIOC_DECODER_CMD</constant> sends a command to the 61 + decoder, <constant>VIDIOC_TRY_DECODER_CMD</constant> can be used to 62 + try a command without actually executing it. To send a command applications 63 + must initialize all fields of a &v4l2-decoder-cmd; and call 64 + <constant>VIDIOC_DECODER_CMD</constant> or <constant>VIDIOC_TRY_DECODER_CMD</constant> 65 + with a pointer to this structure.</para> 66 + 67 + <para>The <structfield>cmd</structfield> field must contain the 68 + command code. Some commands use the <structfield>flags</structfield> field for 69 + additional information. 70 + </para> 71 + 72 + <para>A <function>write</function>() or &VIDIOC-STREAMON; call sends an implicit 73 + START command to the decoder if it has not been started yet. 74 + </para> 75 + 76 + <para>A <function>close</function>() or &VIDIOC-STREAMOFF; call of a streaming 77 + file descriptor sends an implicit immediate STOP command to the decoder, and all 78 + buffered data is discarded.</para> 79 + 80 + <para>These ioctls are optional, not all drivers may support 81 + them. They were introduced in Linux 3.3.</para> 82 + 83 + <table pgwide="1" frame="none" id="v4l2-decoder-cmd"> 84 + <title>struct <structname>v4l2_decoder_cmd</structname></title> 85 + <tgroup cols="5"> 86 + &cs-str; 87 + <tbody valign="top"> 88 + <row> 89 + <entry>__u32</entry> 90 + <entry><structfield>cmd</structfield></entry> 91 + <entry></entry> 92 + <entry></entry> 93 + <entry>The decoder command, see <xref linkend="decoder-cmds" />.</entry> 94 + </row> 95 + <row> 96 + <entry>__u32</entry> 97 + <entry><structfield>flags</structfield></entry> 98 + <entry></entry> 99 + <entry></entry> 100 + <entry>Flags to go with the command. If no flags are defined for 101 + this command, drivers and applications must set this field to zero.</entry> 102 + </row> 103 + <row> 104 + <entry>union</entry> 105 + <entry>(anonymous)</entry> 106 + <entry></entry> 107 + <entry></entry> 108 + <entry></entry> 109 + </row> 110 + <row> 111 + <entry></entry> 112 + <entry>struct</entry> 113 + <entry><structfield>start</structfield></entry> 114 + <entry></entry> 115 + <entry>Structure containing additional data for the 116 + <constant>V4L2_DEC_CMD_START</constant> command.</entry> 117 + </row> 118 + <row> 119 + <entry></entry> 120 + <entry></entry> 121 + <entry>__s32</entry> 122 + <entry><structfield>speed</structfield></entry> 123 + <entry>Playback speed and direction. The playback speed is defined as 124 + <structfield>speed</structfield>/1000 of the normal speed. So 1000 is normal playback. 125 + Negative numbers denote reverse playback, so -1000 does reverse playback at normal 126 + speed. Speeds -1, 0 and 1 have special meanings: speed 0 is shorthand for 1000 127 + (normal playback). A speed of 1 steps just one frame forward, a speed of -1 steps 128 + just one frame back. 129 + </entry> 130 + </row> 131 + <row> 132 + <entry></entry> 133 + <entry></entry> 134 + <entry>__u32</entry> 135 + <entry><structfield>format</structfield></entry> 136 + <entry>Format restrictions. This field is set by the driver, not the 137 + application. Possible values are <constant>V4L2_DEC_START_FMT_NONE</constant> if 138 + there are no format restrictions or <constant>V4L2_DEC_START_FMT_GOP</constant> 139 + if the decoder operates on full GOPs (<wordasword>Group Of Pictures</wordasword>). 140 + This is usually the case for reverse playback: the decoder needs full GOPs, which 141 + it can then play in reverse order. So to implement reverse playback the application 142 + must feed the decoder the last GOP in the video file, then the GOP before that, etc. etc. 143 + </entry> 144 + </row> 145 + <row> 146 + <entry></entry> 147 + <entry>struct</entry> 148 + <entry><structfield>stop</structfield></entry> 149 + <entry></entry> 150 + <entry>Structure containing additional data for the 151 + <constant>V4L2_DEC_CMD_STOP</constant> command.</entry> 152 + </row> 153 + <row> 154 + <entry></entry> 155 + <entry></entry> 156 + <entry>__u64</entry> 157 + <entry><structfield>pts</structfield></entry> 158 + <entry>Stop playback at this <structfield>pts</structfield> or immediately 159 + if the playback is already past that timestamp. Leave to 0 if you want to stop after the 160 + last frame was decoded. 161 + </entry> 162 + </row> 163 + <row> 164 + <entry></entry> 165 + <entry>struct</entry> 166 + <entry><structfield>raw</structfield></entry> 167 + <entry></entry> 168 + <entry></entry> 169 + </row> 170 + <row> 171 + <entry></entry> 172 + <entry></entry> 173 + <entry>__u32</entry> 174 + <entry><structfield>data</structfield>[16]</entry> 175 + <entry>Reserved for future extensions. Drivers and 176 + applications must set the array to zero.</entry> 177 + </row> 178 + </tbody> 179 + </tgroup> 180 + </table> 181 + 182 + <table pgwide="1" frame="none" id="decoder-cmds"> 183 + <title>Decoder Commands</title> 184 + <tgroup cols="3"> 185 + &cs-def; 186 + <tbody valign="top"> 187 + <row> 188 + <entry><constant>V4L2_DEC_CMD_START</constant></entry> 189 + <entry>0</entry> 190 + <entry>Start the decoder. When the decoder is already 191 + running or paused, this command will just change the playback speed. 192 + That means that calling <constant>V4L2_DEC_CMD_START</constant> when 193 + the decoder was paused will <emphasis>not</emphasis> resume the decoder. 194 + You have to explicitly call <constant>V4L2_DEC_CMD_RESUME</constant> for that. 195 + This command has one flag: 196 + <constant>V4L2_DEC_CMD_START_MUTE_AUDIO</constant>. If set, then audio will 197 + be muted when playing back at a non-standard speed. 198 + </entry> 199 + </row> 200 + <row> 201 + <entry><constant>V4L2_DEC_CMD_STOP</constant></entry> 202 + <entry>1</entry> 203 + <entry>Stop the decoder. When the decoder is already stopped, 204 + this command does nothing. This command has two flags: 205 + if <constant>V4L2_DEC_CMD_STOP_TO_BLACK</constant> is set, then the decoder will 206 + set the picture to black after it stopped decoding. Otherwise the last image will 207 + repeat. If <constant>V4L2_DEC_CMD_STOP_IMMEDIATELY</constant> is set, then the decoder 208 + stops immediately (ignoring the <structfield>pts</structfield> value), otherwise it 209 + will keep decoding until timestamp >= pts or until the last of the pending data from 210 + its internal buffers was decoded. 211 + </entry> 212 + </row> 213 + <row> 214 + <entry><constant>V4L2_DEC_CMD_PAUSE</constant></entry> 215 + <entry>2</entry> 216 + <entry>Pause the decoder. When the decoder has not been 217 + started yet, the driver will return an &EPERM;. When the decoder is 218 + already paused, this command does nothing. This command has one flag: 219 + if <constant>V4L2_DEC_CMD_PAUSE_TO_BLACK</constant> is set, then set the 220 + decoder output to black when paused. 221 + </entry> 222 + </row> 223 + <row> 224 + <entry><constant>V4L2_DEC_CMD_RESUME</constant></entry> 225 + <entry>3</entry> 226 + <entry>Resume decoding after a PAUSE command. When the 227 + decoder has not been started yet, the driver will return an &EPERM;. 228 + When the decoder is already running, this command does nothing. No 229 + flags are defined for this command.</entry> 230 + </row> 231 + </tbody> 232 + </tgroup> 233 + </table> 234 + 235 + </refsect1> 236 + 237 + <refsect1> 238 + &return-value; 239 + 240 + <variablelist> 241 + <varlistentry> 242 + <term><errorcode>EINVAL</errorcode></term> 243 + <listitem> 244 + <para>The <structfield>cmd</structfield> field is invalid.</para> 245 + </listitem> 246 + </varlistentry> 247 + <varlistentry> 248 + <term><errorcode>EPERM</errorcode></term> 249 + <listitem> 250 + <para>The application sent a PAUSE or RESUME command when 251 + the decoder was not running.</para> 252 + </listitem> 253 + </varlistentry> 254 + </variablelist> 255 + </refsect1> 256 + </refentry>
+5 -4
Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml
··· 74 74 encoding will continue until the end of the current <wordasword>Group 75 75 Of Pictures</wordasword>, otherwise it will stop immediately.</para> 76 76 77 - <para>A <function>read</function>() call sends a START command to 78 - the encoder if it has not been started yet. After a STOP command, 77 + <para>A <function>read</function>() or &VIDIOC-STREAMON; call sends an implicit 78 + START command to the encoder if it has not been started yet. After a STOP command, 79 79 <function>read</function>() calls will read the remaining data 80 80 buffered by the driver. When the buffer is empty, 81 81 <function>read</function>() will return zero and the next 82 82 <function>read</function>() call will restart the encoder.</para> 83 83 84 - <para>A <function>close</function>() call sends an immediate STOP 85 - to the encoder, and all buffered data is discarded.</para> 84 + <para>A <function>close</function>() or &VIDIOC-STREAMOFF; call of a streaming 85 + file descriptor sends an implicit immediate STOP to the encoder, and all buffered 86 + data is discarded.</para> 86 87 87 88 <para>These ioctls are optional, not all drivers may support 88 89 them. They were introduced in Linux 2.6.21.</para>
+14 -2
Documentation/DocBook/media/v4l/vidioc-g-jpegcomp.xml
··· 57 57 <refsect1> 58 58 <title>Description</title> 59 59 60 + <para>These ioctls are <emphasis role="bold">deprecated</emphasis>. 61 + New drivers and applications should use <link linkend="jpeg-controls"> 62 + JPEG class controls</link> for image quality and JPEG markers control. 63 + </para> 64 + 60 65 <para>[to do]</para> 61 66 62 67 <para>Ronald Bultje elaborates:</para> ··· 91 86 <row> 92 87 <entry>int</entry> 93 88 <entry><structfield>quality</structfield></entry> 94 - <entry></entry> 89 + <entry>Deprecated. If <link linkend="jpeg-quality-control"><constant> 90 + V4L2_CID_JPEG_IMAGE_QUALITY</constant></link> control is exposed by 91 + a driver applications should use it instead and ignore this field. 92 + </entry> 95 93 </row> 96 94 <row> 97 95 <entry>int</entry> ··· 124 116 <row> 125 117 <entry>__u32</entry> 126 118 <entry><structfield>jpeg_markers</structfield></entry> 127 - <entry>See <xref linkend="jpeg-markers" />.</entry> 119 + <entry>See <xref linkend="jpeg-markers"/>. Deprecated. 120 + If <link linkend="jpeg-active-marker-control"><constant> 121 + V4L2_CID_JPEG_ACTIVE_MARKER</constant></link> control 122 + is exposed by a driver applications should use it instead 123 + and ignore this field.</entry> 128 124 </row> 129 125 </tbody> 130 126 </tgroup>
+55 -51
Documentation/DocBook/media/v4l/vidioc-g-selection.xml
··· 58 58 59 59 <para>The ioctls are used to query and configure selection rectangles.</para> 60 60 61 - <para> To query the cropping (composing) rectangle set <structfield> 62 - &v4l2-selection;::type </structfield> to the respective buffer type. Do not 63 - use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE 61 + <para> To query the cropping (composing) rectangle set &v4l2-selection; 62 + <structfield> type </structfield> field to the respective buffer type. 63 + Do not use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE 64 64 </constant> instead of <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE 65 65 </constant>. Use <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> instead of 66 66 <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE </constant>. The next step is 67 - setting <structfield> &v4l2-selection;::target </structfield> to value 68 - <constant> V4L2_SEL_TGT_CROP_ACTIVE </constant> (<constant> 67 + setting the value of &v4l2-selection; <structfield>target</structfield> field 68 + to <constant> V4L2_SEL_TGT_CROP_ACTIVE </constant> (<constant> 69 69 V4L2_SEL_TGT_COMPOSE_ACTIVE </constant>). Please refer to table <xref 70 70 linkend="v4l2-sel-target" /> or <xref linkend="selection-api" /> for additional 71 - targets. Fields <structfield> &v4l2-selection;::flags </structfield> and 72 - <structfield> &v4l2-selection;::reserved </structfield> are ignored and they 73 - must be filled with zeros. The driver fills the rest of the structure or 71 + targets. The <structfield>flags</structfield> and <structfield>reserved 72 + </structfield> fields of &v4l2-selection; are ignored and they must be filled 73 + with zeros. The driver fills the rest of the structure or 74 74 returns &EINVAL; if incorrect buffer type or target was used. If cropping 75 75 (composing) is not supported then the active rectangle is not mutable and it is 76 - always equal to the bounds rectangle. Finally, structure <structfield> 77 - &v4l2-selection;::r </structfield> is filled with the current cropping 76 + always equal to the bounds rectangle. Finally, the &v4l2-rect; 77 + <structfield>r</structfield> rectangle is filled with the current cropping 78 78 (composing) coordinates. The coordinates are expressed in driver-dependent 79 79 units. The only exception are rectangles for images in raw formats, whose 80 80 coordinates are always expressed in pixels. </para> 81 81 82 - <para> To change the cropping (composing) rectangle set <structfield> 83 - &v4l2-selection;::type </structfield> to the respective buffer type. Do not 82 + <para> To change the cropping (composing) rectangle set the &v4l2-selection; 83 + <structfield>type</structfield> field to the respective buffer type. Do not 84 84 use multiplanar buffers. Use <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE 85 85 </constant> instead of <constant> V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE 86 86 </constant>. Use <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> instead of 87 87 <constant> V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE </constant>. The next step is 88 - setting <structfield> &v4l2-selection;::target </structfield> to value 89 - <constant> V4L2_SEL_TGT_CROP_ACTIVE </constant> (<constant> 88 + setting the value of &v4l2-selection; <structfield>target</structfield> to 89 + <constant>V4L2_SEL_TGT_CROP_ACTIVE</constant> (<constant> 90 90 V4L2_SEL_TGT_COMPOSE_ACTIVE </constant>). Please refer to table <xref 91 91 linkend="v4l2-sel-target" /> or <xref linkend="selection-api" /> for additional 92 - targets. Set desired active area into the field <structfield> 93 - &v4l2-selection;::r </structfield>. Field <structfield> 94 - &v4l2-selection;::reserved </structfield> is ignored and must be filled with 95 - zeros. The driver may adjust the rectangle coordinates. An application may 96 - introduce constraints to control rounding behaviour. Set the field 97 - <structfield> &v4l2-selection;::flags </structfield> to one of values: 92 + targets. The &v4l2-rect; <structfield>r</structfield> rectangle need to be 93 + set to the desired active area. Field &v4l2-selection; <structfield> reserved 94 + </structfield> is ignored and must be filled with zeros. The driver may adjust 95 + coordinates of the requested rectangle. An application may 96 + introduce constraints to control rounding behaviour. The &v4l2-selection; 97 + <structfield>flags</structfield> field must be set to one of the following: 98 98 99 99 <itemizedlist> 100 100 <listitem> ··· 129 129 130 130 <orderedlist> 131 131 <listitem> 132 - <para>Satisfy constraints from <structfield>&v4l2-selection;::flags</structfield>.</para> 132 + <para>Satisfy constraints from &v4l2-selection; <structfield>flags</structfield>.</para> 133 133 </listitem> 134 134 <listitem> 135 135 <para>Adjust width, height, left, and top to hardware limits and alignments.</para> ··· 145 145 </listitem> 146 146 </orderedlist> 147 147 148 - On success the field <structfield> &v4l2-selection;::r </structfield> contains 148 + On success the &v4l2-rect; <structfield>r</structfield> field contains 149 149 the adjusted rectangle. When the parameters are unsuitable the application may 150 150 modify the cropping (composing) or image parameters and repeat the cycle until 151 151 satisfactory parameters have been negotiated. If constraints flags have to be ··· 162 162 <tbody valign="top"> 163 163 <row> 164 164 <entry><constant>V4L2_SEL_TGT_CROP_ACTIVE</constant></entry> 165 - <entry>0</entry> 166 - <entry>area that is currently cropped by hardware</entry> 165 + <entry>0x0000</entry> 166 + <entry>The area that is currently cropped by hardware.</entry> 167 167 </row> 168 168 <row> 169 169 <entry><constant>V4L2_SEL_TGT_CROP_DEFAULT</constant></entry> 170 - <entry>1</entry> 171 - <entry>suggested cropping rectangle that covers the "whole picture"</entry> 170 + <entry>0x0001</entry> 171 + <entry>Suggested cropping rectangle that covers the "whole picture".</entry> 172 172 </row> 173 173 <row> 174 174 <entry><constant>V4L2_SEL_TGT_CROP_BOUNDS</constant></entry> 175 - <entry>2</entry> 176 - <entry>limits for the cropping rectangle</entry> 175 + <entry>0x0002</entry> 176 + <entry>Limits for the cropping rectangle.</entry> 177 177 </row> 178 178 <row> 179 179 <entry><constant>V4L2_SEL_TGT_COMPOSE_ACTIVE</constant></entry> 180 - <entry>256</entry> 181 - <entry>area to which data are composed by hardware</entry> 180 + <entry>0x0100</entry> 181 + <entry>The area to which data is composed by hardware.</entry> 182 182 </row> 183 183 <row> 184 184 <entry><constant>V4L2_SEL_TGT_COMPOSE_DEFAULT</constant></entry> 185 - <entry>257</entry> 186 - <entry>suggested composing rectangle that covers the "whole picture"</entry> 185 + <entry>0x0101</entry> 186 + <entry>Suggested composing rectangle that covers the "whole picture".</entry> 187 187 </row> 188 188 <row> 189 189 <entry><constant>V4L2_SEL_TGT_COMPOSE_BOUNDS</constant></entry> 190 - <entry>258</entry> 191 - <entry>limits for the composing rectangle</entry> 190 + <entry>0x0102</entry> 191 + <entry>Limits for the composing rectangle.</entry> 192 192 </row> 193 193 <row> 194 194 <entry><constant>V4L2_SEL_TGT_COMPOSE_PADDED</constant></entry> 195 - <entry>259</entry> 196 - <entry>the active area and all padding pixels that are inserted or modified by the hardware</entry> 195 + <entry>0x0103</entry> 196 + <entry>The active area and all padding pixels that are inserted or modified by hardware.</entry> 197 197 </row> 198 198 </tbody> 199 199 </tgroup> ··· 209 209 <row> 210 210 <entry><constant>V4L2_SEL_FLAG_GE</constant></entry> 211 211 <entry>0x00000001</entry> 212 - <entry>indicate that adjusted rectangle must contain a rectangle from <structfield>&v4l2-selection;::r</structfield></entry> 212 + <entry>Indicates that the adjusted rectangle must contain the original 213 + &v4l2-selection; <structfield>r</structfield> rectangle.</entry> 213 214 </row> 214 215 <row> 215 216 <entry><constant>V4L2_SEL_FLAG_LE</constant></entry> 216 217 <entry>0x00000002</entry> 217 - <entry>indicate that adjusted rectangle must be inside a rectangle from <structfield>&v4l2-selection;::r</structfield></entry> 218 + <entry>Indicates that the adjusted rectangle must be inside the original 219 + &v4l2-rect; <structfield>r</structfield> rectangle.</entry> 218 220 </row> 219 221 </tbody> 220 222 </tgroup> ··· 247 245 <row> 248 246 <entry>__u32</entry> 249 247 <entry><structfield>type</structfield></entry> 250 - <entry>Type of the buffer (from &v4l2-buf-type;)</entry> 248 + <entry>Type of the buffer (from &v4l2-buf-type;).</entry> 251 249 </row> 252 250 <row> 253 251 <entry>__u32</entry> 254 252 <entry><structfield>target</structfield></entry> 255 - <entry>used to select between <link linkend="v4l2-sel-target"> cropping and composing rectangles </link></entry> 253 + <entry>Used to select between <link linkend="v4l2-sel-target"> cropping 254 + and composing rectangles</link>.</entry> 256 255 </row> 257 256 <row> 258 257 <entry>__u32</entry> 259 258 <entry><structfield>flags</structfield></entry> 260 - <entry>control over coordinates adjustments, refer to <link linkend="v4l2-sel-flags">selection flags</link></entry> 259 + <entry>Flags controlling the selection rectangle adjustments, refer to 260 + <link linkend="v4l2-sel-flags">selection flags</link>.</entry> 261 261 </row> 262 262 <row> 263 263 <entry>&v4l2-rect;</entry> 264 264 <entry><structfield>r</structfield></entry> 265 - <entry>selection rectangle</entry> 265 + <entry>The selection rectangle.</entry> 266 266 </row> 267 267 <row> 268 268 <entry>__u32</entry> 269 269 <entry><structfield>reserved[9]</structfield></entry> 270 - <entry>Reserved fields for future use</entry> 270 + <entry>Reserved fields for future use.</entry> 271 271 </row> 272 272 </tbody> 273 273 </tgroup> ··· 282 278 <varlistentry> 283 279 <term><errorcode>EINVAL</errorcode></term> 284 280 <listitem> 285 - <para>The buffer <structfield> &v4l2-selection;::type </structfield> 286 - or <structfield> &v4l2-selection;::target </structfield> is not supported, or 287 - the <structfield> &v4l2-selection;::flags </structfield> are invalid.</para> 281 + <para>Given buffer type <structfield>type</structfield> or 282 + the selection target <structfield>target</structfield> is not supported, 283 + or the <structfield>flags</structfield> argument is not valid.</para> 288 284 </listitem> 289 285 </varlistentry> 290 286 <varlistentry> 291 287 <term><errorcode>ERANGE</errorcode></term> 292 288 <listitem> 293 - <para>it is not possible to adjust a rectangle <structfield> 294 - &v4l2-selection;::r </structfield> that satisfies all contraints from 295 - <structfield> &v4l2-selection;::flags </structfield>.</para> 289 + <para>It is not possible to adjust &v4l2-rect; <structfield> 290 + r</structfield> rectangle to satisfy all contraints given in the 291 + <structfield>flags</structfield> argument.</para> 296 292 </listitem> 297 293 </varlistentry> 298 294 <varlistentry> 299 295 <term><errorcode>EBUSY</errorcode></term> 300 296 <listitem> 301 - <para>it is not possible to apply change of selection rectangle at the moment. 302 - Usually because streaming is in progress.</para> 297 + <para>It is not possible to apply change of the selection rectangle 298 + at the moment. Usually because streaming is in progress.</para> 303 299 </listitem> 304 300 </varlistentry> 305 301 </variablelist>
+33 -3
Documentation/DocBook/media/v4l/vidioc-querycap.xml
··· 124 124 <row> 125 125 <entry>__u32</entry> 126 126 <entry><structfield>capabilities</structfield></entry> 127 - <entry>Device capabilities, see <xref 128 - linkend="device-capabilities" />.</entry> 127 + <entry>Available capabilities of the physical device as a whole, see <xref 128 + linkend="device-capabilities" />. The same physical device can export 129 + multiple devices in /dev (e.g. /dev/videoX, /dev/vbiY and /dev/radioZ). 130 + The <structfield>capabilities</structfield> field should contain a union 131 + of all capabilities available around the several V4L2 devices exported 132 + to userspace. 133 + For all those devices the <structfield>capabilities</structfield> field 134 + returns the same set of capabilities. This allows applications to open 135 + just one of the devices (typically the video device) and discover whether 136 + video, vbi and/or radio are also supported. 137 + </entry> 129 138 </row> 130 139 <row> 131 140 <entry>__u32</entry> 132 - <entry><structfield>reserved</structfield>[4]</entry> 141 + <entry><structfield>device_caps</structfield></entry> 142 + <entry>Device capabilities of the opened device, see <xref 143 + linkend="device-capabilities" />. Should contain the available capabilities 144 + of that specific device node. So, for example, <structfield>device_caps</structfield> 145 + of a radio device will only contain radio related capabilities and 146 + no video or vbi capabilities. This field is only set if the <structfield>capabilities</structfield> 147 + field contains the <constant>V4L2_CAP_DEVICE_CAPS</constant> capability. 148 + Only the <structfield>capabilities</structfield> field can have the 149 + <constant>V4L2_CAP_DEVICE_CAPS</constant> capability, <structfield>device_caps</structfield> 150 + will never set <constant>V4L2_CAP_DEVICE_CAPS</constant>. 151 + </entry> 152 + </row> 153 + <row> 154 + <entry>__u32</entry> 155 + <entry><structfield>reserved</structfield>[3]</entry> 133 156 <entry>Reserved for future extensions. Drivers must set 134 157 this array to zero.</entry> 135 158 </row> ··· 298 275 <entry>0x04000000</entry> 299 276 <entry>The device supports the <link 300 277 linkend="mmap">streaming</link> I/O method.</entry> 278 + </row> 279 + <row> 280 + <entry><constant>V4L2_CAP_DEVICE_CAPS</constant></entry> 281 + <entry>0x80000000</entry> 282 + <entry>The driver fills the <structfield>device_caps</structfield> 283 + field. This capability can only appear in the <structfield>capabilities</structfield> 284 + field and never in the <structfield>device_caps</structfield> field.</entry> 301 285 </row> 302 286 </tbody> 303 287 </tgroup>
+3 -3
Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
··· 96 96 <row> 97 97 <entry>__u32</entry> 98 98 <entry><structfield>reserved</structfield>[7]</entry> 99 - <entry>Reserved for future extensions. Drivers and 100 - applications must set the array to zero.</entry> 99 + <entry>Reserved for future extensions. Applications 100 + must set the array to zero.</entry> 101 101 </row> 102 102 </tbody> 103 103 </tgroup> ··· 112 112 <term><errorcode>EINVAL</errorcode></term> 113 113 <listitem> 114 114 <para>The <structfield>tuner</structfield> index is out of 115 - bounds or the value in the <structfield>type</structfield> field is 115 + bounds, the wrap_around value is not supported or the value in the <structfield>type</structfield> field is 116 116 wrong.</para> 117 117 </listitem> 118 118 </varlistentry>
+1
Documentation/dvb/cards.txt
··· 119 119 - Compro Videomate DVB-T300 120 120 - Compro Videomate DVB-T200 121 121 - AVerMedia AVerTVHD MCE A180 122 + - KWorld PC150-U ATSC Hybrid 122 123
+11
Documentation/dvb/lmedm04.txt
··· 66 66 For LME2510C 67 67 dd if=US290D.sys ibs=1 skip=33152 count=3697 of=dvb-usb-lme2510c-s0194.fw 68 68 69 + --------------------------------------------------------------------- 70 + 71 + The m88rs2000 tuner driver can be found in windows/system32/drivers 72 + 73 + US2B0D.sys (dated 29 Jun 2010) 74 + 75 + dd if=US2B0D.sys ibs=1 skip=34432 count=3871 of=dvb-usb-lme2510c-rs2000.fw 76 + 77 + We need to modify id of rs2000 firmware or it will warm boot id 3344:1120. 78 + 79 + echo -ne \\xF0\\x22 | dd conv=notrunc bs=1 count=2 seek=266 of=dvb-usb-lme2510c-rs2000.fw 69 80 70 81 Copy the firmware file(s) to /lib/firmware
+1
Documentation/video4linux/CARDLIST.cx23885
··· 32 32 31 -> Leadtek Winfast PxDVR3200 H XC4000 [107d:6f39] 33 33 32 -> MPX-885 34 34 33 -> Mygica X8507 [14f1:8502] 35 + 34 -> TerraTec Cinergy T PCIe Dual [153b:117e]
+3 -1
Documentation/video4linux/CARDLIST.cx88
··· 59 59 58 -> Pinnacle PCTV HD 800i [11bd:0051] 60 60 59 -> DViCO FusionHDTV 5 PCI nano [18ac:d530] 61 61 60 -> Pinnacle Hybrid PCTV [12ab:1788] 62 - 61 -> Leadtek TV2000 XP Global [107d:6f18,107d:6618] 62 + 61 -> Leadtek TV2000 XP Global [107d:6f18,107d:6618,107d:6619] 63 63 62 -> PowerColor RA330 [14f1:ea3d] 64 64 63 -> Geniatech X8000-MT DVBT [14f1:8852] 65 65 64 -> DViCO FusionHDTV DVB-T PRO [18ac:db30] ··· 87 87 86 -> TeVii S464 DVB-S/S2 [d464:9022] 88 88 87 -> Leadtek WinFast DTV2000 H PLUS [107d:6f42] 89 89 88 -> Leadtek WinFast DTV1800 H (XC4000) [107d:6f38] 90 + 89 -> Leadtek TV2000 XP Global (SC4100) [107d:6f36] 91 + 90 -> Leadtek TV2000 XP Global (XC4100) [107d:6f43]
+7 -3
Documentation/video4linux/CARDLIST.em28xx
··· 7 7 6 -> Terratec Cinergy 200 USB (em2800) 8 8 7 -> Leadtek Winfast USB II (em2800) [0413:6023] 9 9 8 -> Kworld USB2800 (em2800) 10 - 9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,1b80:e304,2304:0207,2304:021a] 10 + 9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,1b80:e304,2304:0207,2304:021a,093b:a003] 11 11 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] 12 12 11 -> Terratec Hybrid XS (em2880) 13 13 12 -> Kworld PVR TV 2800 RF (em2820/em2840) ··· 61 61 61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840) 62 62 62 -> Gadmei TVR200 (em2820/em2840) 63 63 63 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303] 64 - 64 -> Easy Cap Capture DC-60 (em2860) 64 + 64 -> Easy Cap Capture DC-60 (em2860) [1b80:e309] 65 65 65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515] 66 66 66 -> Empire dual TV (em2880) 67 67 67 -> Terratec Grabby (em2860) [0ccd:0096,0ccd:10AF] ··· 76 76 76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340] 77 77 77 -> EM2874 Leadership ISDBT (em2874) 78 78 78 -> PCTV nanoStick T2 290e (em28174) 79 - 79 -> Terratec Cinergy H5 (em2884) [0ccd:10a2,0ccd:10ad] 79 + 79 -> Terratec Cinergy H5 (em2884) [0ccd:008e,0ccd:00ac,0ccd:10a2,0ccd:10ad] 80 80 80 -> PCTV DVB-S2 Stick (460e) (em28174) 81 81 81 -> Hauppauge WinTV HVR 930C (em2884) [2040:1605] 82 82 82 -> Terratec Cinergy HTC Stick (em2884) [0ccd:00b2] 83 + 83 -> Honestech Vidbox NW03 (em2860) [eb1a:5006] 84 + 84 -> MaxMedia UB425-TC (em2874) [1b80:e425] 85 + 85 -> PCTV QuatroStick (510e) (em2884) [2304:0242] 86 + 86 -> PCTV QuatroStick nano (520e) (em2884) [2013:0251]
+1
Documentation/video4linux/CARDLIST.saa7134
··· 187 187 186 -> Beholder BeholdTV 501 [5ace:5010] 188 188 187 -> Beholder BeholdTV 503 FM [5ace:5030] 189 189 188 -> Sensoray 811/911 [6000:0811,6000:0911] 190 + 189 -> Kworld PC150-U [17de:a134]
+2 -1
Documentation/video4linux/CARDLIST.tuner
··· 78 78 tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner 79 79 tuner=79 - Philips PAL/SECAM multi (FM1216 MK5) 80 80 tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough 81 - tuner=81 - Xceive 4000 tuner 82 81 tuner=81 - Partsnic (Daewoo) PTI-5NF05 83 82 tuner=82 - Philips CU1216L 84 83 tuner=83 - NXP TDA18271 85 84 tuner=84 - Sony BTF-Pxn01Z 86 85 tuner=85 - Philips FQ1236 MK5 87 86 tuner=86 - Tena TNF5337 MFD 87 + tuner=87 - Xceive 4000 tuner 88 + tuner=88 - Xceive 5000C tuner
+178
Documentation/video4linux/fimc.txt
··· 1 + Samsung S5P/EXYNOS4 FIMC driver 2 + 3 + Copyright (C) 2012 Samsung Electronics Co., Ltd. 4 + --------------------------------------------------------------------------- 5 + 6 + The FIMC (Fully Interactive Mobile Camera) device available in Samsung 7 + SoC Application Processors is an integrated camera host interface, color 8 + space converter, image resizer and rotator. It's also capable of capturing 9 + data from LCD controller (FIMD) through the SoC internal writeback data 10 + path. There are multiple FIMC instances in the SoCs (up to 4), having 11 + slightly different capabilities, like pixel alignment constraints, rotator 12 + availability, LCD writeback support, etc. The driver is located at 13 + drivers/media/video/s5p-fimc directory. 14 + 15 + 1. Supported SoCs 16 + ================= 17 + 18 + S5PC100 (mem-to-mem only), S5PV210, EXYNOS4210 19 + 20 + 2. Supported features 21 + ===================== 22 + 23 + - camera parallel interface capture (ITU-R.BT601/565); 24 + - camera serial interface capture (MIPI-CSI2); 25 + - memory-to-memory processing (color space conversion, scaling, mirror 26 + and rotation); 27 + - dynamic pipeline re-configuration at runtime (re-attachment of any FIMC 28 + instance to any parallel video input or any MIPI-CSI front-end); 29 + - runtime PM and system wide suspend/resume 30 + 31 + Not currently supported: 32 + - LCD writeback input 33 + - per frame clock gating (mem-to-mem) 34 + 35 + 3. Files partitioning 36 + ===================== 37 + 38 + - media device driver 39 + drivers/media/video/s5p-fimc/fimc-mdevice.[ch] 40 + 41 + - camera capture video device driver 42 + drivers/media/video/s5p-fimc/fimc-capture.c 43 + 44 + - MIPI-CSI2 receiver subdev 45 + drivers/media/video/s5p-fimc/mipi-csis.[ch] 46 + 47 + - video post-processor (mem-to-mem) 48 + drivers/media/video/s5p-fimc/fimc-core.c 49 + 50 + - common files 51 + drivers/media/video/s5p-fimc/fimc-core.h 52 + drivers/media/video/s5p-fimc/fimc-reg.h 53 + drivers/media/video/s5p-fimc/regs-fimc.h 54 + 55 + 4. User space interfaces 56 + ======================== 57 + 58 + 4.1. Media device interface 59 + 60 + The driver supports Media Controller API as defined at 61 + http://http://linuxtv.org/downloads/v4l-dvb-apis/media_common.html 62 + The media device driver name is "SAMSUNG S5P FIMC". 63 + 64 + The purpose of this interface is to allow changing assignment of FIMC instances 65 + to the SoC peripheral camera input at runtime and optionally to control internal 66 + connections of the MIPI-CSIS device(s) to the FIMC entities. 67 + 68 + The media device interface allows to configure the SoC for capturing image 69 + data from the sensor through more than one FIMC instance (e.g. for simultaneous 70 + viewfinder and still capture setup). 71 + Reconfiguration is done by enabling/disabling media links created by the driver 72 + during initialization. The internal device topology can be easily discovered 73 + through media entity and links enumeration. 74 + 75 + 4.2. Memory-to-memory video node 76 + 77 + V4L2 memory-to-memory interface at /dev/video? device node. This is standalone 78 + video device, it has no media pads. However please note the mem-to-mem and 79 + capture video node operation on same FIMC instance is not allowed. The driver 80 + detects such cases but the applications should prevent them to avoid an 81 + undefined behaviour. 82 + 83 + 4.3. Capture video node 84 + 85 + The driver supports V4L2 Video Capture Interface as defined at: 86 + http://linuxtv.org/downloads/v4l-dvb-apis/devices.html 87 + 88 + At the capture and mem-to-mem video nodes only the multi-planar API is 89 + supported. For more details see: 90 + http://linuxtv.org/downloads/v4l-dvb-apis/planar-apis.html 91 + 92 + 4.4. Camera capture subdevs 93 + 94 + Each FIMC instance exports a sub-device node (/dev/v4l-subdev?), a sub-device 95 + node is also created per each available and enabled at the platform level 96 + MIPI-CSI receiver device (currently up to two). 97 + 98 + 4.5. sysfs 99 + 100 + In order to enable more precise camera pipeline control through the sub-device 101 + API the driver creates a sysfs entry associated with "s5p-fimc-md" platform 102 + device. The entry path is: /sys/platform/devices/s5p-fimc-md/subdev_conf_mode. 103 + 104 + In typical use case there could be a following capture pipeline configuration: 105 + sensor subdev -> mipi-csi subdev -> fimc subdev -> video node 106 + 107 + When we configure these devices through sub-device API at user space, the 108 + configuration flow must be from left to right, and the video node is 109 + configured as last one. 110 + When we don't use sub-device user space API the whole configuration of all 111 + devices belonging to the pipeline is done at the video node driver. 112 + The sysfs entry allows to instruct the capture node driver not to configure 113 + the sub-devices (format, crop), to avoid resetting the subdevs' configuration 114 + when the last configuration steps at the video node is performed. 115 + 116 + For full sub-device control support (subdevs configured at user space before 117 + starting streaming): 118 + # echo "sub-dev" > /sys/platform/devices/s5p-fimc-md/subdev_conf_mode 119 + 120 + For V4L2 video node control only (subdevs configured internally by the host 121 + driver): 122 + # echo "vid-dev" > /sys/platform/devices/s5p-fimc-md/subdev_conf_mode 123 + This is a default option. 124 + 125 + 5. Device mapping to video and subdev device nodes 126 + ================================================== 127 + 128 + There are associated two video device nodes with each device instance in 129 + hardware - video capture and mem-to-mem and additionally a subdev node for 130 + more precise FIMC capture subsystem control. In addition a separate v4l2 131 + sub-device node is created per each MIPI-CSIS device. 132 + 133 + How to find out which /dev/video? or /dev/v4l-subdev? is assigned to which 134 + device? 135 + 136 + You can either grep through the kernel log to find relevant information, i.e. 137 + # dmesg | grep -i fimc 138 + (note that udev, if present, might still have rearranged the video nodes), 139 + 140 + or retrieve the information from /dev/media? with help of the media-ctl tool: 141 + # media-ctl -p 142 + 143 + 6. Platform support 144 + =================== 145 + 146 + The machine code (plat-s5p and arch/arm/mach-*) must select following options 147 + 148 + CONFIG_S5P_DEV_FIMC0 mandatory 149 + CONFIG_S5P_DEV_FIMC1 \ 150 + CONFIG_S5P_DEV_FIMC2 | optional 151 + CONFIG_S5P_DEV_FIMC3 | 152 + CONFIG_S5P_SETUP_FIMC / 153 + CONFIG_S5P_SETUP_MIPIPHY \ 154 + CONFIG_S5P_DEV_CSIS0 | optional for MIPI-CSI interface 155 + CONFIG_S5P_DEV_CSIS1 / 156 + 157 + Except that, relevant s5p_device_fimc? should be registered in the machine code 158 + in addition to a "s5p-fimc-md" platform device to which the media device driver 159 + is bound. The "s5p-fimc-md" device instance is required even if only mem-to-mem 160 + operation is used. 161 + 162 + The description of sensor(s) attached to FIMC/MIPI-CSIS camera inputs should be 163 + passed as the "s5p-fimc-md" device platform_data. The platform data structure 164 + is defined in file include/media/s5p_fimc.h. 165 + 166 + 7. Build 167 + ======== 168 + 169 + This driver depends on following config options: 170 + PLAT_S5P, 171 + PM_RUNTIME, 172 + I2C, 173 + REGULATOR, 174 + VIDEO_V4L2_SUBDEV_API, 175 + 176 + If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m) 177 + two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and 178 + optional s5p-csis.ko (MIPI-CSI receiver subdev).
+1
Documentation/video4linux/gspca.txt
··· 217 217 sonixj 06f8:3004 Hercules Classic Silver 218 218 sonixj 06f8:3008 Hercules Deluxe Optical Glass 219 219 pac7302 06f8:3009 Hercules Classic Link 220 + pac7302 06f8:301b Hercules Link 220 221 nw80x 0728:d001 AVerMedia Camguard 221 222 spca508 0733:0110 ViewQuest VQ110 222 223 spca501 0733:0401 Intel Create and Share
+1 -1
arch/arm/mach-imx/clock-imx27.c
··· 661 661 _REGISTER_CLOCK(NULL, "dma", dma_clk) 662 662 _REGISTER_CLOCK(NULL, "rtic", rtic_clk) 663 663 _REGISTER_CLOCK(NULL, "brom", brom_clk) 664 - _REGISTER_CLOCK(NULL, "emma", emma_clk) 664 + _REGISTER_CLOCK("m2m-emmaprp.0", NULL, emma_clk) 665 665 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk) 666 666 _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) 667 667 _REGISTER_CLOCK(NULL, "emi", emi_clk)
+2
arch/arm/mach-imx/devices-imx27.h
··· 50 50 extern const struct imx_mx2_camera_data imx27_mx2_camera_data; 51 51 #define imx27_add_mx2_camera(pdata) \ 52 52 imx_add_mx2_camera(&imx27_mx2_camera_data, pdata) 53 + #define imx27_add_mx2_emmaprp(pdata) \ 54 + imx_add_mx2_emmaprp(&imx27_mx2_camera_data) 53 55 54 56 extern const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data; 55 57 #define imx27_add_mxc_ehci_otg(pdata) \
+18
arch/arm/plat-mxc/devices/platform-mx2-camera.c
··· 62 62 res, data->iobaseemmaprp ? 4 : 2, 63 63 pdata, sizeof(*pdata), DMA_BIT_MASK(32)); 64 64 } 65 + 66 + struct platform_device *__init imx_add_mx2_emmaprp( 67 + const struct imx_mx2_camera_data *data) 68 + { 69 + struct resource res[] = { 70 + { 71 + .start = data->iobaseemmaprp, 72 + .end = data->iobaseemmaprp + data->iosizeemmaprp - 1, 73 + .flags = IORESOURCE_MEM, 74 + }, { 75 + .start = data->irqemmaprp, 76 + .end = data->irqemmaprp, 77 + .flags = IORESOURCE_IRQ, 78 + }, 79 + }; 80 + return imx_add_platform_device_dmamask("m2m-emmaprp", 0, 81 + res, 2, NULL, 0, DMA_BIT_MASK(32)); 82 + }
+2
arch/arm/plat-mxc/include/mach/devices-common.h
··· 223 223 struct platform_device *__init imx_add_mx2_camera( 224 224 const struct imx_mx2_camera_data *data, 225 225 const struct mx2_camera_platform_data *pdata); 226 + struct platform_device *__init imx_add_mx2_emmaprp( 227 + const struct imx_mx2_camera_data *data); 226 228 227 229 #include <mach/mxc_ehci.h> 228 230 struct imx_mxc_ehci_data {
+10
drivers/hid/hid-core.c
··· 2026 2026 if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST && 2027 2027 hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST) 2028 2028 return true; 2029 + /* 2030 + * The Keene FM transmitter USB device has the same USB ID as 2031 + * the Logitech AudioHub Speaker, but it should ignore the hid. 2032 + * Check if the name is that of the Keene device. 2033 + * For reference: the name of the AudioHub is 2034 + * "HOLTEK AudioHub Speaker". 2035 + */ 2036 + if (hdev->product == USB_DEVICE_ID_LOGITECH_AUDIOHUB && 2037 + !strcmp(hdev->name, "HOLTEK B-LINK USB Audio ")) 2038 + return true; 2029 2039 break; 2030 2040 case USB_VENDOR_ID_SOUNDGRAPH: 2031 2041 if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST &&
+1
drivers/hid/hid-ids.h
··· 471 471 #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 472 472 473 473 #define USB_VENDOR_ID_LOGITECH 0x046d 474 + #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e 474 475 #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 475 476 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 476 477 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
+2 -2
drivers/media/common/tuners/Makefile
··· 29 29 obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o 30 30 obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o 31 31 32 - ccflags-y += -Idrivers/media/dvb/dvb-core 33 - ccflags-y += -Idrivers/media/dvb/frontends 32 + ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core 33 + ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+6 -3
drivers/media/common/tuners/max2165.c
··· 168 168 int i; 169 169 170 170 if (0 == divisor) 171 - return -1; 171 + return -EINVAL; 172 172 173 173 q = dividend / divisor; 174 174 remainder = dividend - q * divisor; ··· 194 194 u8 tf_ntch; 195 195 u32 t; 196 196 u32 quotient, fraction; 197 + int ret; 197 198 198 199 /* Set PLL divider according to RF frequency */ 199 - fixpt_div32(freq / 1000, priv->config->osc_clk * 1000, 200 - &quotient, &fraction); 200 + ret = fixpt_div32(freq / 1000, priv->config->osc_clk * 1000, 201 + &quotient, &fraction); 202 + if (ret != 0) 203 + return ret; 201 204 202 205 /* 20-bit fraction */ 203 206 fraction >>= 12;
+2 -2
drivers/media/common/tuners/mt2063.c
··· 350 350 /* 351 351 * ToDo: Add code here to implement a OS blocking 352 352 */ 353 - msleep(10); 353 + msleep(100); 354 354 355 355 return 0; 356 356 } ··· 2226 2226 .info = { 2227 2227 .name = "MT2063 Silicon Tuner", 2228 2228 .frequency_min = 45000000, 2229 - .frequency_max = 850000000, 2229 + .frequency_max = 865000000, 2230 2230 .frequency_step = 0, 2231 2231 }, 2232 2232
-4
drivers/media/common/tuners/mt2063.h
··· 23 23 return NULL; 24 24 } 25 25 26 - int mt2063_setTune(struct dvb_frontend *fe, u32 f_in, 27 - u32 bw_in, 28 - enum MTTune_atv_standard tv_type); 29 - 30 26 /* FIXME: Should use the standard DVB attachment interfaces */ 31 27 unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe); 32 28 unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe);
+4
drivers/media/common/tuners/tuner-types.c
··· 1868 1868 .params = tuner_tena_tnf_5337_params, 1869 1869 .count = ARRAY_SIZE(tuner_tena_tnf_5337_params), 1870 1870 }, 1871 + [TUNER_XC5000C] = { /* Xceive 5000C */ 1872 + .name = "Xceive 5000C tuner", 1873 + /* see xc5000.c for details */ 1874 + }, 1871 1875 }; 1872 1876 EXPORT_SYMBOL(tuners); 1873 1877
+41 -6
drivers/media/common/tuners/xc5000.c
··· 49 49 #define dprintk(level, fmt, arg...) if (debug >= level) \ 50 50 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) 51 51 52 - #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw" 53 - #define XC5000_DEFAULT_FIRMWARE_SIZE 12401 54 - 55 52 struct xc5000_priv { 56 53 struct tuner_i2c_props i2c_props; 57 54 struct list_head hybrid_tuner_instance_list; ··· 59 62 u8 video_standard; 60 63 u8 rf_mode; 61 64 u8 radio_input; 65 + 66 + int chip_id; 62 67 }; 63 68 64 69 /* Misc Defines */ ··· 202 203 {"FM Radio-INPUT1", 0x0208, 0x9002}, 203 204 {"FM Radio-INPUT1_MONO", 0x0278, 0x9002} 204 205 }; 206 + 207 + 208 + struct xc5000_fw_cfg { 209 + char *name; 210 + u16 size; 211 + }; 212 + 213 + static const struct xc5000_fw_cfg xc5000a_1_6_114 = { 214 + .name = "dvb-fe-xc5000-1.6.114.fw", 215 + .size = 12401, 216 + }; 217 + 218 + static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = { 219 + .name = "dvb-fe-xc5000c-41.024.5-31875.fw", 220 + .size = 16503, 221 + }; 222 + 223 + static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) 224 + { 225 + switch (chip_id) { 226 + default: 227 + case XC5000A: 228 + return &xc5000a_1_6_114; 229 + case XC5000C: 230 + return &xc5000c_41_024_5_31875; 231 + } 232 + } 205 233 206 234 static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); 207 235 static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); ··· 578 552 struct xc5000_priv *priv = fe->tuner_priv; 579 553 const struct firmware *fw; 580 554 int ret; 555 + const struct xc5000_fw_cfg *desired_fw = 556 + xc5000_assign_firmware(priv->chip_id); 581 557 582 558 /* request the firmware, this will block and timeout */ 583 559 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", 584 - XC5000_DEFAULT_FIRMWARE); 560 + desired_fw->name); 585 561 586 - ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, 562 + ret = request_firmware(&fw, desired_fw->name, 587 563 priv->i2c_props.adap->dev.parent); 588 564 if (ret) { 589 565 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); ··· 597 569 ret = XC_RESULT_SUCCESS; 598 570 } 599 571 600 - if (fw->size != XC5000_DEFAULT_FIRMWARE_SIZE) { 572 + if (fw->size != desired_fw->size) { 601 573 printk(KERN_ERR "xc5000: firmware incorrect size\n"); 602 574 ret = XC_RESULT_RESET_FAILURE; 603 575 } else { ··· 1166 1138 1167 1139 if (priv->radio_input == 0) 1168 1140 priv->radio_input = cfg->radio_input; 1141 + 1142 + /* don't override chip id if it's already been set 1143 + unless explicitly specified */ 1144 + if ((priv->chip_id == 0) || (cfg->chip_id)) 1145 + /* use default chip id if none specified, set to 0 so 1146 + it can be overridden if this is a hybrid driver */ 1147 + priv->chip_id = (cfg->chip_id) ? cfg->chip_id : 0; 1169 1148 1170 1149 /* Check if firmware has been loaded. It is possible that another 1171 1150 instance of the driver has loaded the firmware.
+5
drivers/media/common/tuners/xc5000.h
··· 27 27 struct dvb_frontend; 28 28 struct i2c_adapter; 29 29 30 + #define XC5000A 1 31 + #define XC5000C 2 32 + 30 33 struct xc5000_config { 31 34 u8 i2c_address; 32 35 u32 if_khz; 33 36 u8 radio_input; 37 + 38 + int chip_id; 34 39 }; 35 40 36 41 /* xc5000 callback command */
+1
drivers/media/dvb/ddbridge/ddbridge-core.c
··· 578 578 struct drxk_config config; 579 579 580 580 memset(&config, 0, sizeof(config)); 581 + config.microcode_name = "drxk_a3.mc"; 581 582 config.adr = 0x29 + (input->nr & 1); 582 583 583 584 fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
-2
drivers/media/dvb/ddbridge/ddbridge.h
··· 32 32 #include <asm/dma.h> 33 33 #include <linux/dvb/frontend.h> 34 34 #include <linux/dvb/ca.h> 35 - #include <linux/dvb/video.h> 36 - #include <linux/dvb/audio.h> 37 35 #include <linux/socket.h> 38 36 39 37 #include "dmxdev.h"
+2
drivers/media/dvb/dvb-core/dvb_frontend.c
··· 655 655 dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__); 656 656 re_tune = true; 657 657 fepriv->state = FESTATE_TUNED; 658 + } else { 659 + re_tune = false; 658 660 } 659 661 660 662 if (fe->ops.tune)
+19
drivers/media/dvb/dvb-usb/Kconfig
··· 361 361 help 362 362 Say Y here to support the E3C EC168 DVB-T USB2.0 receiver. 363 363 364 + config DVB_USB_AZ6007 365 + tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support" 366 + depends on DVB_USB 367 + select DVB_DRXK if !DVB_FE_CUSTOMISE 368 + select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE 369 + help 370 + Say Y here to support theAfatech AF9005 based DVB-T/DVB-C receivers. 371 + 364 372 config DVB_USB_AZ6027 365 373 tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support" 366 374 depends on DVB_USB ··· 386 378 select DVB_IX2505V if !DVB_FE_CUSTOMISE 387 379 select DVB_STV0299 if !DVB_FE_CUSTOMISE 388 380 select DVB_PLL if !DVB_FE_CUSTOMISE 381 + select DVB_M88RS2000 if !DVB_FE_CUSTOMISE 389 382 help 390 383 Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . 391 384 ··· 412 403 select VIDEO_TVEEPROM 413 404 help 414 405 Say Y here to support the MxL111SF USB2.0 DTV receiver. 406 + 407 + config DVB_USB_RTL28XXU 408 + tristate "Realtek RTL28xxU DVB USB support" 409 + depends on DVB_USB && EXPERIMENTAL 410 + select DVB_RTL2830 411 + select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE 412 + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE 413 + select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE 414 + help 415 + Say Y here to support the Realtek RTL28xxU DVB USB receiver.
+10 -4
drivers/media/dvb/dvb-usb/Makefile
··· 54 54 dvb-usb-opera-objs = opera1.o 55 55 obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o 56 56 57 - 58 57 dvb-usb-af9005-objs = af9005.o af9005-fe.o 59 58 obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o 60 59 ··· 87 88 dvb-usb-ec168-objs = ec168.o 88 89 obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o 89 90 91 + dvb-usb-az6007-objs = az6007.o 92 + obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o 93 + 90 94 dvb-usb-az6027-objs = az6027.o 91 95 obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o 92 96 ··· 107 105 obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o 108 106 obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o 109 107 110 - ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 108 + dvb-usb-rtl28xxu-objs = rtl28xxu.o 109 + obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o 110 + 111 + ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core 112 + ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/ 111 113 # due to tuner-xc3028 112 - ccflags-y += -Idrivers/media/common/tuners 113 - EXTRA_CFLAGS += -Idrivers/media/dvb/ttpci 114 + ccflags-y += -I$(srctree)/drivers/media/common/tuners 115 + ccflags-y += -I$(srctree)/drivers/media/dvb/ttpci 114 116
+49
drivers/media/dvb/dvb-usb/af9015.c
··· 1164 1164 return ret; 1165 1165 } 1166 1166 1167 + /* override tuner callbacks for resource locking */ 1168 + static int af9015_tuner_init(struct dvb_frontend *fe) 1169 + { 1170 + int ret; 1171 + struct dvb_usb_adapter *adap = fe->dvb->priv; 1172 + struct af9015_state *priv = adap->dev->priv; 1173 + 1174 + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) 1175 + return -EAGAIN; 1176 + 1177 + ret = priv->tuner_init[adap->id](fe); 1178 + 1179 + mutex_unlock(&adap->dev->usb_mutex); 1180 + 1181 + return ret; 1182 + } 1183 + 1184 + /* override tuner callbacks for resource locking */ 1185 + static int af9015_tuner_sleep(struct dvb_frontend *fe) 1186 + { 1187 + int ret; 1188 + struct dvb_usb_adapter *adap = fe->dvb->priv; 1189 + struct af9015_state *priv = adap->dev->priv; 1190 + 1191 + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) 1192 + return -EAGAIN; 1193 + 1194 + ret = priv->tuner_sleep[adap->id](fe); 1195 + 1196 + mutex_unlock(&adap->dev->usb_mutex); 1197 + 1198 + return ret; 1199 + } 1200 + 1201 + 1167 1202 static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) 1168 1203 { 1169 1204 int ret; ··· 1318 1283 static int af9015_tuner_attach(struct dvb_usb_adapter *adap) 1319 1284 { 1320 1285 int ret; 1286 + struct af9015_state *state = adap->dev->priv; 1321 1287 deb_info("%s:\n", __func__); 1322 1288 1323 1289 switch (af9015_af9013_config[adap->id].tuner) { ··· 1376 1340 err("Unknown tuner id:%d", 1377 1341 af9015_af9013_config[adap->id].tuner); 1378 1342 } 1343 + 1344 + if (adap->fe_adap[0].fe->ops.tuner_ops.init) { 1345 + state->tuner_init[adap->id] = 1346 + adap->fe_adap[0].fe->ops.tuner_ops.init; 1347 + adap->fe_adap[0].fe->ops.tuner_ops.init = af9015_tuner_init; 1348 + } 1349 + 1350 + if (adap->fe_adap[0].fe->ops.tuner_ops.sleep) { 1351 + state->tuner_sleep[adap->id] = 1352 + adap->fe_adap[0].fe->ops.tuner_ops.sleep; 1353 + adap->fe_adap[0].fe->ops.tuner_ops.sleep = af9015_tuner_sleep; 1354 + } 1355 + 1379 1356 return ret; 1380 1357 } 1381 1358
+2
drivers/media/dvb/dvb-usb/af9015.h
··· 108 108 int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status); 109 109 int (*init[2]) (struct dvb_frontend *fe); 110 110 int (*sleep[2]) (struct dvb_frontend *fe); 111 + int (*tuner_init[2]) (struct dvb_frontend *fe); 112 + int (*tuner_sleep[2]) (struct dvb_frontend *fe); 111 113 }; 112 114 113 115 struct af9015_config {
+32 -6
drivers/media/dvb/dvb-usb/anysee.c
··· 58 58 u8 *rbuf, u8 rlen) 59 59 { 60 60 struct anysee_state *state = d->priv; 61 - int act_len, ret; 61 + int act_len, ret, i; 62 62 u8 buf[64]; 63 63 64 64 memcpy(&buf[0], sbuf, slen); ··· 73 73 /* We need receive one message more after dvb_usb_generic_rw due 74 74 to weird transaction flow, which is 1 x send + 2 x receive. */ 75 75 ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); 76 - if (!ret) { 76 + if (ret) 77 + goto error_unlock; 78 + 79 + /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32 80 + * (EPIPE, Broken pipe). Function supports currently msleep() as a 81 + * parameter but I would not like to use it, since according to 82 + * Documentation/timers/timers-howto.txt it should not be used such 83 + * short, under < 20ms, sleeps. Repeating failed message would be 84 + * better choice as not to add unwanted delays... 85 + * Fixing that correctly is one of those or both; 86 + * 1) use repeat if possible 87 + * 2) add suitable delay 88 + */ 89 + 90 + /* get answer, retry few times if error returned */ 91 + for (i = 0; i < 3; i++) { 77 92 /* receive 2nd answer */ 78 93 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 79 94 d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf), 80 95 &act_len, 2000); 81 - if (ret) 82 - err("%s: recv bulk message failed: %d", __func__, ret); 83 - else { 96 + 97 + if (ret) { 98 + deb_info("%s: recv bulk message failed: %d", 99 + __func__, ret); 100 + } else { 84 101 deb_xfer("<<< "); 85 102 debug_dump(buf, rlen, deb_xfer); 86 103 87 104 if (buf[63] != 0x4f) 88 105 deb_info("%s: cmd failed\n", __func__); 106 + 107 + break; 89 108 } 90 109 } 91 110 111 + if (ret) { 112 + /* all retries failed, it is fatal */ 113 + err("%s: recv bulk message failed: %d", __func__, ret); 114 + goto error_unlock; 115 + } 116 + 92 117 /* read request, copy returned data to return buf */ 93 - if (!ret && rbuf && rlen) 118 + if (rbuf && rlen) 94 119 memcpy(rbuf, buf, rlen); 95 120 121 + error_unlock: 96 122 mutex_unlock(&anysee_usb_mutex); 97 123 98 124 return ret;
+957
drivers/media/dvb/dvb-usb/az6007.c
··· 1 + /* 2 + * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones 3 + * 4 + * Copyright (c) Henry Wang <Henry.wang@AzureWave.com> 5 + * 6 + * This driver was made publicly available by Terratec, at: 7 + * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz 8 + * The original driver's license is GPL, as declared with MODULE_LICENSE() 9 + * 10 + * Copyright (c) 2010-2011 Mauro Carvalho Chehab <mchehab@redhat.com> 11 + * Driver modified by in order to work with upstream drxk driver, and 12 + * tons of bugs got fixed. 13 + * 14 + * This program is free software; you can redistribute it and/or modify 15 + * it under the terms of the GNU General Public License as published by 16 + * the Free Software Foundation under version 2 of the License. 17 + * 18 + * This program is distributed in the hope that it will be useful, 19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 + * GNU General Public License for more details. 22 + */ 23 + 24 + #include "drxk.h" 25 + #include "mt2063.h" 26 + #include "dvb_ca_en50221.h" 27 + 28 + #define DVB_USB_LOG_PREFIX "az6007" 29 + #include "dvb-usb.h" 30 + 31 + /* debug */ 32 + int dvb_usb_az6007_debug; 33 + module_param_named(debug, dvb_usb_az6007_debug, int, 0644); 34 + MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." 35 + DVB_USB_DEBUG_STATUS); 36 + 37 + #define deb_info(args...) dprintk(dvb_usb_az6007_debug, 0x01, args) 38 + #define deb_xfer(args...) dprintk(dvb_usb_az6007_debug, 0x02, args) 39 + #define deb_rc(args...) dprintk(dvb_usb_az6007_debug, 0x04, args) 40 + #define deb_fe(args...) dprintk(dvb_usb_az6007_debug, 0x08, args) 41 + 42 + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 43 + 44 + /* Known requests (Cypress FX2 firmware + az6007 "private" ones*/ 45 + 46 + #define FX2_OED 0xb5 47 + #define AZ6007_READ_DATA 0xb7 48 + #define AZ6007_I2C_RD 0xb9 49 + #define AZ6007_POWER 0xbc 50 + #define AZ6007_I2C_WR 0xbd 51 + #define FX2_SCON1 0xc0 52 + #define AZ6007_TS_THROUGH 0xc7 53 + #define AZ6007_READ_IR 0xb4 54 + 55 + struct az6007_device_state { 56 + struct mutex mutex; 57 + struct mutex ca_mutex; 58 + struct dvb_ca_en50221 ca; 59 + unsigned warm:1; 60 + int (*gate_ctrl) (struct dvb_frontend *, int); 61 + unsigned char data[4096]; 62 + }; 63 + 64 + static struct drxk_config terratec_h7_drxk = { 65 + .adr = 0x29, 66 + .parallel_ts = true, 67 + .dynamic_clk = true, 68 + .single_master = true, 69 + .enable_merr_cfg = true, 70 + .no_i2c_bridge = false, 71 + .chunk_size = 64, 72 + .mpeg_out_clk_strength = 0x02, 73 + .microcode_name = "dvb-usb-terratec-h7-drxk.fw", 74 + }; 75 + 76 + static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 77 + { 78 + struct dvb_usb_adapter *adap = fe->sec_priv; 79 + struct az6007_device_state *st; 80 + int status = 0; 81 + 82 + deb_info("%s: %s\n", __func__, enable ? "enable" : "disable"); 83 + 84 + if (!adap) 85 + return -EINVAL; 86 + 87 + st = adap->dev->priv; 88 + 89 + if (!st) 90 + return -EINVAL; 91 + 92 + if (enable) 93 + status = st->gate_ctrl(fe, 1); 94 + else 95 + status = st->gate_ctrl(fe, 0); 96 + 97 + return status; 98 + } 99 + 100 + static struct mt2063_config az6007_mt2063_config = { 101 + .tuner_address = 0x60, 102 + .refclock = 36125000, 103 + }; 104 + 105 + static int __az6007_read(struct usb_device *udev, u8 req, u16 value, 106 + u16 index, u8 *b, int blen) 107 + { 108 + int ret; 109 + 110 + ret = usb_control_msg(udev, 111 + usb_rcvctrlpipe(udev, 0), 112 + req, 113 + USB_TYPE_VENDOR | USB_DIR_IN, 114 + value, index, b, blen, 5000); 115 + if (ret < 0) { 116 + warn("usb read operation failed. (%d)", ret); 117 + return -EIO; 118 + } 119 + 120 + deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, 121 + index); 122 + debug_dump(b, blen, deb_xfer); 123 + 124 + return ret; 125 + } 126 + 127 + static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value, 128 + u16 index, u8 *b, int blen) 129 + { 130 + struct az6007_device_state *st = d->priv; 131 + int ret; 132 + 133 + if (mutex_lock_interruptible(&st->mutex) < 0) 134 + return -EAGAIN; 135 + 136 + ret = __az6007_read(d->udev, req, value, index, b, blen); 137 + 138 + mutex_unlock(&st->mutex); 139 + 140 + return ret; 141 + } 142 + 143 + static int __az6007_write(struct usb_device *udev, u8 req, u16 value, 144 + u16 index, u8 *b, int blen) 145 + { 146 + int ret; 147 + 148 + deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, 149 + index); 150 + debug_dump(b, blen, deb_xfer); 151 + 152 + if (blen > 64) { 153 + err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n", 154 + blen); 155 + return -EOPNOTSUPP; 156 + } 157 + 158 + ret = usb_control_msg(udev, 159 + usb_sndctrlpipe(udev, 0), 160 + req, 161 + USB_TYPE_VENDOR | USB_DIR_OUT, 162 + value, index, b, blen, 5000); 163 + if (ret != blen) { 164 + err("usb write operation failed. (%d)", ret); 165 + return -EIO; 166 + } 167 + 168 + return 0; 169 + } 170 + 171 + static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value, 172 + u16 index, u8 *b, int blen) 173 + { 174 + struct az6007_device_state *st = d->priv; 175 + int ret; 176 + 177 + if (mutex_lock_interruptible(&st->mutex) < 0) 178 + return -EAGAIN; 179 + 180 + ret = __az6007_write(d->udev, req, value, index, b, blen); 181 + 182 + mutex_unlock(&st->mutex); 183 + 184 + return ret; 185 + } 186 + 187 + static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 188 + { 189 + struct dvb_usb_device *d = adap->dev; 190 + 191 + deb_info("%s: %s", __func__, onoff ? "enable" : "disable"); 192 + 193 + return az6007_write(d, 0xbc, onoff, 0, NULL, 0); 194 + } 195 + 196 + /* remote control stuff (does not work with my box) */ 197 + static int az6007_rc_query(struct dvb_usb_device *d) 198 + { 199 + struct az6007_device_state *st = d->priv; 200 + unsigned code = 0; 201 + 202 + az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); 203 + 204 + if (st->data[1] == 0x44) 205 + return 0; 206 + 207 + if ((st->data[1] ^ st->data[2]) == 0xff) 208 + code = st->data[1]; 209 + else 210 + code = st->data[1] << 8 | st->data[2]; 211 + 212 + if ((st->data[3] ^ st->data[4]) == 0xff) 213 + code = code << 8 | st->data[3]; 214 + else 215 + code = code << 16 | st->data[3] << 8 | st->data[4]; 216 + 217 + rc_keydown(d->rc_dev, code, st->data[5]); 218 + 219 + return 0; 220 + } 221 + 222 + static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, 223 + int slot, 224 + int address) 225 + { 226 + struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 227 + struct az6007_device_state *state = (struct az6007_device_state *)d->priv; 228 + 229 + int ret; 230 + u8 req; 231 + u16 value; 232 + u16 index; 233 + int blen; 234 + u8 *b; 235 + 236 + if (slot != 0) 237 + return -EINVAL; 238 + 239 + b = kmalloc(12, GFP_KERNEL); 240 + if (!b) 241 + return -ENOMEM; 242 + 243 + mutex_lock(&state->ca_mutex); 244 + 245 + req = 0xC1; 246 + value = address; 247 + index = 0; 248 + blen = 1; 249 + 250 + ret = az6007_read(d, req, value, index, b, blen); 251 + if (ret < 0) { 252 + warn("usb in operation failed. (%d)", ret); 253 + ret = -EINVAL; 254 + } else { 255 + ret = b[0]; 256 + } 257 + 258 + mutex_unlock(&state->ca_mutex); 259 + kfree(b); 260 + return ret; 261 + } 262 + 263 + static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, 264 + int slot, 265 + int address, 266 + u8 value) 267 + { 268 + struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 269 + struct az6007_device_state *state = (struct az6007_device_state *)d->priv; 270 + 271 + int ret; 272 + u8 req; 273 + u16 value1; 274 + u16 index; 275 + int blen; 276 + 277 + deb_info("%s %d", __func__, slot); 278 + if (slot != 0) 279 + return -EINVAL; 280 + 281 + mutex_lock(&state->ca_mutex); 282 + req = 0xC2; 283 + value1 = address; 284 + index = value; 285 + blen = 0; 286 + 287 + ret = az6007_write(d, req, value1, index, NULL, blen); 288 + if (ret != 0) 289 + warn("usb out operation failed. (%d)", ret); 290 + 291 + mutex_unlock(&state->ca_mutex); 292 + return ret; 293 + } 294 + 295 + static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca, 296 + int slot, 297 + u8 address) 298 + { 299 + struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 300 + struct az6007_device_state *state = (struct az6007_device_state *)d->priv; 301 + 302 + int ret; 303 + u8 req; 304 + u16 value; 305 + u16 index; 306 + int blen; 307 + u8 *b; 308 + 309 + if (slot != 0) 310 + return -EINVAL; 311 + 312 + b = kmalloc(12, GFP_KERNEL); 313 + if (!b) 314 + return -ENOMEM; 315 + 316 + mutex_lock(&state->ca_mutex); 317 + 318 + req = 0xC3; 319 + value = address; 320 + index = 0; 321 + blen = 2; 322 + 323 + ret = az6007_read(d, req, value, index, b, blen); 324 + if (ret < 0) { 325 + warn("usb in operation failed. (%d)", ret); 326 + ret = -EINVAL; 327 + } else { 328 + if (b[0] == 0) 329 + warn("Read CI IO error"); 330 + 331 + ret = b[1]; 332 + deb_info("read cam data = %x from 0x%x", b[1], value); 333 + } 334 + 335 + mutex_unlock(&state->ca_mutex); 336 + kfree(b); 337 + return ret; 338 + } 339 + 340 + static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca, 341 + int slot, 342 + u8 address, 343 + u8 value) 344 + { 345 + struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 346 + struct az6007_device_state *state = (struct az6007_device_state *)d->priv; 347 + 348 + int ret; 349 + u8 req; 350 + u16 value1; 351 + u16 index; 352 + int blen; 353 + 354 + if (slot != 0) 355 + return -EINVAL; 356 + 357 + mutex_lock(&state->ca_mutex); 358 + req = 0xC4; 359 + value1 = address; 360 + index = value; 361 + blen = 0; 362 + 363 + ret = az6007_write(d, req, value1, index, NULL, blen); 364 + if (ret != 0) { 365 + warn("usb out operation failed. (%d)", ret); 366 + goto failed; 367 + } 368 + 369 + failed: 370 + mutex_unlock(&state->ca_mutex); 371 + return ret; 372 + } 373 + 374 + static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) 375 + { 376 + struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 377 + 378 + int ret; 379 + u8 req; 380 + u16 value; 381 + u16 index; 382 + int blen; 383 + u8 *b; 384 + 385 + b = kmalloc(12, GFP_KERNEL); 386 + if (!b) 387 + return -ENOMEM; 388 + 389 + req = 0xC8; 390 + value = 0; 391 + index = 0; 392 + blen = 1; 393 + 394 + ret = az6007_read(d, req, value, index, b, blen); 395 + if (ret < 0) { 396 + warn("usb in operation failed. (%d)", ret); 397 + ret = -EIO; 398 + } else{ 399 + ret = b[0]; 400 + } 401 + kfree(b); 402 + return ret; 403 + } 404 + 405 + static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) 406 + { 407 + struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 408 + struct az6007_device_state *state = (struct az6007_device_state *)d->priv; 409 + 410 + int ret, i; 411 + u8 req; 412 + u16 value; 413 + u16 index; 414 + int blen; 415 + 416 + mutex_lock(&state->ca_mutex); 417 + 418 + req = 0xC6; 419 + value = 1; 420 + index = 0; 421 + blen = 0; 422 + 423 + ret = az6007_write(d, req, value, index, NULL, blen); 424 + if (ret != 0) { 425 + warn("usb out operation failed. (%d)", ret); 426 + goto failed; 427 + } 428 + 429 + msleep(500); 430 + req = 0xC6; 431 + value = 0; 432 + index = 0; 433 + blen = 0; 434 + 435 + ret = az6007_write(d, req, value, index, NULL, blen); 436 + if (ret != 0) { 437 + warn("usb out operation failed. (%d)", ret); 438 + goto failed; 439 + } 440 + 441 + for (i = 0; i < 15; i++) { 442 + msleep(100); 443 + 444 + if (CI_CamReady(ca, slot)) { 445 + deb_info("CAM Ready"); 446 + break; 447 + } 448 + } 449 + msleep(5000); 450 + 451 + failed: 452 + mutex_unlock(&state->ca_mutex); 453 + return ret; 454 + } 455 + 456 + static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) 457 + { 458 + return 0; 459 + } 460 + 461 + static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) 462 + { 463 + struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 464 + struct az6007_device_state *state = (struct az6007_device_state *)d->priv; 465 + 466 + int ret; 467 + u8 req; 468 + u16 value; 469 + u16 index; 470 + int blen; 471 + 472 + deb_info("%s", __func__); 473 + mutex_lock(&state->ca_mutex); 474 + req = 0xC7; 475 + value = 1; 476 + index = 0; 477 + blen = 0; 478 + 479 + ret = az6007_write(d, req, value, index, NULL, blen); 480 + if (ret != 0) { 481 + warn("usb out operation failed. (%d)", ret); 482 + goto failed; 483 + } 484 + 485 + failed: 486 + mutex_unlock(&state->ca_mutex); 487 + return ret; 488 + } 489 + 490 + static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) 491 + { 492 + struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; 493 + struct az6007_device_state *state = (struct az6007_device_state *)d->priv; 494 + int ret; 495 + u8 req; 496 + u16 value; 497 + u16 index; 498 + int blen; 499 + u8 *b; 500 + 501 + b = kmalloc(12, GFP_KERNEL); 502 + if (!b) 503 + return -ENOMEM; 504 + mutex_lock(&state->ca_mutex); 505 + 506 + req = 0xC5; 507 + value = 0; 508 + index = 0; 509 + blen = 1; 510 + 511 + ret = az6007_read(d, req, value, index, b, blen); 512 + if (ret < 0) { 513 + warn("usb in operation failed. (%d)", ret); 514 + ret = -EIO; 515 + } else 516 + ret = 0; 517 + 518 + if (!ret && b[0] == 1) { 519 + ret = DVB_CA_EN50221_POLL_CAM_PRESENT | 520 + DVB_CA_EN50221_POLL_CAM_READY; 521 + } 522 + 523 + mutex_unlock(&state->ca_mutex); 524 + kfree(b); 525 + return ret; 526 + } 527 + 528 + 529 + static void az6007_ci_uninit(struct dvb_usb_device *d) 530 + { 531 + struct az6007_device_state *state; 532 + 533 + deb_info("%s", __func__); 534 + 535 + if (NULL == d) 536 + return; 537 + 538 + state = (struct az6007_device_state *)d->priv; 539 + if (NULL == state) 540 + return; 541 + 542 + if (NULL == state->ca.data) 543 + return; 544 + 545 + dvb_ca_en50221_release(&state->ca); 546 + 547 + memset(&state->ca, 0, sizeof(state->ca)); 548 + } 549 + 550 + 551 + static int az6007_ci_init(struct dvb_usb_adapter *a) 552 + { 553 + struct dvb_usb_device *d = a->dev; 554 + struct az6007_device_state *state = (struct az6007_device_state *)d->priv; 555 + int ret; 556 + 557 + deb_info("%s", __func__); 558 + 559 + mutex_init(&state->ca_mutex); 560 + 561 + state->ca.owner = THIS_MODULE; 562 + state->ca.read_attribute_mem = az6007_ci_read_attribute_mem; 563 + state->ca.write_attribute_mem = az6007_ci_write_attribute_mem; 564 + state->ca.read_cam_control = az6007_ci_read_cam_control; 565 + state->ca.write_cam_control = az6007_ci_write_cam_control; 566 + state->ca.slot_reset = az6007_ci_slot_reset; 567 + state->ca.slot_shutdown = az6007_ci_slot_shutdown; 568 + state->ca.slot_ts_enable = az6007_ci_slot_ts_enable; 569 + state->ca.poll_slot_status = az6007_ci_poll_slot_status; 570 + state->ca.data = d; 571 + 572 + ret = dvb_ca_en50221_init(&a->dvb_adap, 573 + &state->ca, 574 + 0, /* flags */ 575 + 1);/* n_slots */ 576 + if (ret != 0) { 577 + err("Cannot initialize CI: Error %d.", ret); 578 + memset(&state->ca, 0, sizeof(state->ca)); 579 + return ret; 580 + } 581 + 582 + deb_info("CI initialized."); 583 + 584 + return 0; 585 + } 586 + 587 + static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) 588 + { 589 + struct az6007_device_state *st = d->priv; 590 + int ret; 591 + 592 + ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6); 593 + memcpy(mac, st->data, sizeof(mac)); 594 + 595 + if (ret > 0) 596 + deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n", 597 + __func__, mac[0], mac[1], mac[2], 598 + mac[3], mac[4], mac[5]); 599 + 600 + return ret; 601 + } 602 + 603 + static int az6007_frontend_attach(struct dvb_usb_adapter *adap) 604 + { 605 + struct az6007_device_state *st = adap->dev->priv; 606 + 607 + deb_info("attaching demod drxk"); 608 + 609 + adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk, 610 + &adap->dev->i2c_adap); 611 + if (!adap->fe_adap[0].fe) 612 + return -EINVAL; 613 + 614 + adap->fe_adap[0].fe->sec_priv = adap; 615 + st->gate_ctrl = adap->fe_adap[0].fe->ops.i2c_gate_ctrl; 616 + adap->fe_adap[0].fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; 617 + 618 + az6007_ci_init(adap); 619 + 620 + return 0; 621 + } 622 + 623 + static int az6007_tuner_attach(struct dvb_usb_adapter *adap) 624 + { 625 + deb_info("attaching tuner mt2063"); 626 + 627 + /* Attach mt2063 to DVB-C frontend */ 628 + if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) 629 + adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1); 630 + if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe, 631 + &az6007_mt2063_config, 632 + &adap->dev->i2c_adap)) 633 + return -EINVAL; 634 + 635 + if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) 636 + adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0); 637 + 638 + return 0; 639 + } 640 + 641 + int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) 642 + { 643 + struct az6007_device_state *st = d->priv; 644 + int ret; 645 + 646 + deb_info("%s()\n", __func__); 647 + 648 + if (!st->warm) { 649 + mutex_init(&st->mutex); 650 + 651 + ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0); 652 + if (ret < 0) 653 + return ret; 654 + msleep(60); 655 + ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0); 656 + if (ret < 0) 657 + return ret; 658 + msleep(100); 659 + ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0); 660 + if (ret < 0) 661 + return ret; 662 + msleep(20); 663 + ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0); 664 + if (ret < 0) 665 + return ret; 666 + 667 + msleep(400); 668 + ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0); 669 + if (ret < 0) 670 + return ret; 671 + msleep(150); 672 + ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0); 673 + if (ret < 0) 674 + return ret; 675 + msleep(430); 676 + ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); 677 + if (ret < 0) 678 + return ret; 679 + 680 + st->warm = true; 681 + 682 + return 0; 683 + } 684 + 685 + if (!onoff) 686 + return 0; 687 + 688 + az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); 689 + az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0); 690 + 691 + return 0; 692 + } 693 + 694 + /* I2C */ 695 + static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], 696 + int num) 697 + { 698 + struct dvb_usb_device *d = i2c_get_adapdata(adap); 699 + struct az6007_device_state *st = d->priv; 700 + int i, j, len; 701 + int ret = 0; 702 + u16 index; 703 + u16 value; 704 + int length; 705 + u8 req, addr; 706 + 707 + if (mutex_lock_interruptible(&st->mutex) < 0) 708 + return -EAGAIN; 709 + 710 + for (i = 0; i < num; i++) { 711 + addr = msgs[i].addr << 1; 712 + if (((i + 1) < num) 713 + && (msgs[i].len == 1) 714 + && (!msgs[i].flags & I2C_M_RD) 715 + && (msgs[i + 1].flags & I2C_M_RD) 716 + && (msgs[i].addr == msgs[i + 1].addr)) { 717 + /* 718 + * A write + read xfer for the same address, where 719 + * the first xfer has just 1 byte length. 720 + * Need to join both into one operation 721 + */ 722 + if (dvb_usb_az6007_debug & 2) 723 + printk(KERN_DEBUG 724 + "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ", 725 + addr, msgs[i].len, msgs[i + 1].len); 726 + req = AZ6007_I2C_RD; 727 + index = msgs[i].buf[0]; 728 + value = addr | (1 << 8); 729 + length = 6 + msgs[i + 1].len; 730 + len = msgs[i + 1].len; 731 + ret = __az6007_read(d->udev, req, value, index, 732 + st->data, length); 733 + if (ret >= len) { 734 + for (j = 0; j < len; j++) { 735 + msgs[i + 1].buf[j] = st->data[j + 5]; 736 + if (dvb_usb_az6007_debug & 2) 737 + printk(KERN_CONT 738 + "0x%02x ", 739 + msgs[i + 1].buf[j]); 740 + } 741 + } else 742 + ret = -EIO; 743 + i++; 744 + } else if (!(msgs[i].flags & I2C_M_RD)) { 745 + /* write bytes */ 746 + if (dvb_usb_az6007_debug & 2) 747 + printk(KERN_DEBUG 748 + "az6007 I2C xfer write addr=0x%x len=%d: ", 749 + addr, msgs[i].len); 750 + req = AZ6007_I2C_WR; 751 + index = msgs[i].buf[0]; 752 + value = addr | (1 << 8); 753 + length = msgs[i].len - 1; 754 + len = msgs[i].len - 1; 755 + if (dvb_usb_az6007_debug & 2) 756 + printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]); 757 + for (j = 0; j < len; j++) { 758 + st->data[j] = msgs[i].buf[j + 1]; 759 + if (dvb_usb_az6007_debug & 2) 760 + printk(KERN_CONT "0x%02x ", 761 + st->data[j]); 762 + } 763 + ret = __az6007_write(d->udev, req, value, index, 764 + st->data, length); 765 + } else { 766 + /* read bytes */ 767 + if (dvb_usb_az6007_debug & 2) 768 + printk(KERN_DEBUG 769 + "az6007 I2C xfer read addr=0x%x len=%d: ", 770 + addr, msgs[i].len); 771 + req = AZ6007_I2C_RD; 772 + index = msgs[i].buf[0]; 773 + value = addr; 774 + length = msgs[i].len + 6; 775 + len = msgs[i].len; 776 + ret = __az6007_read(d->udev, req, value, index, 777 + st->data, length); 778 + for (j = 0; j < len; j++) { 779 + msgs[i].buf[j] = st->data[j + 5]; 780 + if (dvb_usb_az6007_debug & 2) 781 + printk(KERN_CONT 782 + "0x%02x ", st->data[j + 5]); 783 + } 784 + } 785 + if (dvb_usb_az6007_debug & 2) 786 + printk(KERN_CONT "\n"); 787 + if (ret < 0) 788 + goto err; 789 + } 790 + err: 791 + mutex_unlock(&st->mutex); 792 + 793 + if (ret < 0) { 794 + info("%s ERROR: %i", __func__, ret); 795 + return ret; 796 + } 797 + return num; 798 + } 799 + 800 + static u32 az6007_i2c_func(struct i2c_adapter *adapter) 801 + { 802 + return I2C_FUNC_I2C; 803 + } 804 + 805 + static struct i2c_algorithm az6007_i2c_algo = { 806 + .master_xfer = az6007_i2c_xfer, 807 + .functionality = az6007_i2c_func, 808 + }; 809 + 810 + int az6007_identify_state(struct usb_device *udev, 811 + struct dvb_usb_device_properties *props, 812 + struct dvb_usb_device_description **desc, int *cold) 813 + { 814 + int ret; 815 + u8 *mac; 816 + 817 + mac = kmalloc(6, GFP_ATOMIC); 818 + if (!mac) 819 + return -ENOMEM; 820 + 821 + /* Try to read the mac address */ 822 + ret = __az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); 823 + if (ret == 6) 824 + *cold = 0; 825 + else 826 + *cold = 1; 827 + 828 + kfree(mac); 829 + 830 + if (*cold) { 831 + __az6007_write(udev, 0x09, 1, 0, NULL, 0); 832 + __az6007_write(udev, 0x00, 0, 0, NULL, 0); 833 + __az6007_write(udev, 0x00, 0, 0, NULL, 0); 834 + } 835 + 836 + deb_info("Device is on %s state\n", *cold ? "warm" : "cold"); 837 + return 0; 838 + } 839 + 840 + static struct dvb_usb_device_properties az6007_properties; 841 + 842 + static void az6007_usb_disconnect(struct usb_interface *intf) 843 + { 844 + struct dvb_usb_device *d = usb_get_intfdata(intf); 845 + az6007_ci_uninit(d); 846 + dvb_usb_device_exit(intf); 847 + } 848 + 849 + static int az6007_usb_probe(struct usb_interface *intf, 850 + const struct usb_device_id *id) 851 + { 852 + return dvb_usb_device_init(intf, &az6007_properties, 853 + THIS_MODULE, NULL, adapter_nr); 854 + } 855 + 856 + static struct usb_device_id az6007_usb_table[] = { 857 + {USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007)}, 858 + {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7)}, 859 + {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2)}, 860 + {0}, 861 + }; 862 + 863 + MODULE_DEVICE_TABLE(usb, az6007_usb_table); 864 + 865 + static struct dvb_usb_device_properties az6007_properties = { 866 + .caps = DVB_USB_IS_AN_I2C_ADAPTER, 867 + .usb_ctrl = CYPRESS_FX2, 868 + .firmware = "dvb-usb-terratec-h7-az6007.fw", 869 + .no_reconnect = 1, 870 + .size_of_priv = sizeof(struct az6007_device_state), 871 + .identify_state = az6007_identify_state, 872 + .num_adapters = 1, 873 + .adapter = { 874 + { 875 + .num_frontends = 1, 876 + .fe = {{ 877 + .streaming_ctrl = az6007_streaming_ctrl, 878 + .tuner_attach = az6007_tuner_attach, 879 + .frontend_attach = az6007_frontend_attach, 880 + 881 + /* parameter for the MPEG2-data transfer */ 882 + .stream = { 883 + .type = USB_BULK, 884 + .count = 10, 885 + .endpoint = 0x02, 886 + .u = { 887 + .bulk = { 888 + .buffersize = 4096, 889 + } 890 + } 891 + }, 892 + } } 893 + } }, 894 + .power_ctrl = az6007_power_ctrl, 895 + .read_mac_address = az6007_read_mac_addr, 896 + 897 + .rc.core = { 898 + .rc_interval = 400, 899 + .rc_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, 900 + .module_name = "az6007", 901 + .rc_query = az6007_rc_query, 902 + .allowed_protos = RC_TYPE_NEC, 903 + }, 904 + .i2c_algo = &az6007_i2c_algo, 905 + 906 + .num_device_descs = 2, 907 + .devices = { 908 + { .name = "AzureWave DTV StarBox DVB-T/C USB2.0 (az6007)", 909 + .cold_ids = { &az6007_usb_table[0], NULL }, 910 + .warm_ids = { NULL }, 911 + }, 912 + { .name = "TerraTec DTV StarBox DVB-T/C USB2.0 (az6007)", 913 + .cold_ids = { &az6007_usb_table[1], &az6007_usb_table[2], NULL }, 914 + .warm_ids = { NULL }, 915 + }, 916 + { NULL }, 917 + } 918 + }; 919 + 920 + /* usb specific object needed to register this driver with the usb subsystem */ 921 + static struct usb_driver az6007_usb_driver = { 922 + .name = "dvb_usb_az6007", 923 + .probe = az6007_usb_probe, 924 + .disconnect = az6007_usb_disconnect, 925 + .id_table = az6007_usb_table, 926 + }; 927 + 928 + /* module stuff */ 929 + static int __init az6007_usb_module_init(void) 930 + { 931 + int result; 932 + deb_info("az6007 usb module init\n"); 933 + 934 + result = usb_register(&az6007_usb_driver); 935 + if (result) { 936 + err("usb_register failed. (%d)", result); 937 + return result; 938 + } 939 + 940 + return 0; 941 + } 942 + 943 + static void __exit az6007_usb_module_exit(void) 944 + { 945 + /* deregister this driver from the USB subsystem */ 946 + deb_info("az6007 usb module exit\n"); 947 + usb_deregister(&az6007_usb_driver); 948 + } 949 + 950 + module_init(az6007_usb_module_init); 951 + module_exit(az6007_usb_module_exit); 952 + 953 + MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>"); 954 + MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); 955 + MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones"); 956 + MODULE_VERSION("1.1"); 957 + MODULE_LICENSE("GPL");
+6 -4
drivers/media/dvb/dvb-usb/dib0700_core.c
··· 677 677 u8 toggle; 678 678 679 679 deb_info("%s()\n", __func__); 680 - if (d == NULL) 681 - return; 682 - 683 680 if (d->rc_dev == NULL) { 684 681 /* This will occur if disable_rc_polling=1 */ 682 + kfree(purb->transfer_buffer); 685 683 usb_free_urb(purb); 686 684 return; 687 685 } ··· 688 690 689 691 if (purb->status < 0) { 690 692 deb_info("discontinuing polling\n"); 693 + kfree(purb->transfer_buffer); 691 694 usb_free_urb(purb); 692 695 return; 693 696 } ··· 783 784 dib0700_rc_urb_completion, d); 784 785 785 786 ret = usb_submit_urb(purb, GFP_ATOMIC); 786 - if (ret) 787 + if (ret) { 787 788 err("rc submit urb failed\n"); 789 + kfree(purb->transfer_buffer); 790 + usb_free_urb(purb); 791 + } 788 792 789 793 return ret; 790 794 }
+8
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
··· 51 51 #define USB_VID_PINNACLE 0x2304 52 52 #define USB_VID_PCTV 0x2013 53 53 #define USB_VID_PIXELVIEW 0x1554 54 + #define USB_VID_REALTEK 0x0bda 54 55 #define USB_VID_TECHNOTREND 0x0b48 55 56 #define USB_VID_TERRATEC 0x0ccd 56 57 #define USB_VID_TELESTAR 0x10b9 ··· 81 80 #define USB_PID_ANSONIC_DVBT_USB 0x6000 82 81 #define USB_PID_ANYSEE 0x861f 83 82 #define USB_PID_AZUREWAVE_AD_TU700 0x3237 83 + #define USB_PID_AZUREWAVE_6007 0x0ccd 84 84 #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 85 85 #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 86 86 #define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 ··· 127 125 #define USB_PID_E3C_EC168_3 0xfffb 128 126 #define USB_PID_E3C_EC168_4 0x1001 129 127 #define USB_PID_E3C_EC168_5 0x1002 128 + #define USB_PID_FREECOM_DVBT 0x0160 129 + #define USB_PID_FREECOM_DVBT_2 0x0161 130 130 #define USB_PID_UNIWILL_STK7700P 0x6003 131 131 #define USB_PID_GENIUS_TVGO_DVB_T03 0x4012 132 132 #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 ··· 230 226 #define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 231 227 #define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 232 228 #define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab 229 + #define USB_PID_TERRATEC_H7 0x10b4 230 + #define USB_PID_TERRATEC_H7_2 0x10a3 233 231 #define USB_PID_TERRATEC_T3 0x10a0 234 232 #define USB_PID_TERRATEC_T5 0x10a1 235 233 #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e ··· 255 249 #define USB_PID_PCTV_400E 0x020f 256 250 #define USB_PID_PCTV_450E 0x0222 257 251 #define USB_PID_PCTV_452E 0x021f 252 + #define USB_PID_REALTEK_RTL2831U 0x2831 253 + #define USB_PID_REALTEK_RTL2832U 0x2832 258 254 #define USB_PID_TECHNOTREND_CONNECT_S2_3600 0x3007 259 255 #define USB_PID_TECHNOTREND_CONNECT_S2_3650_CI 0x300a 260 256 #define USB_PID_NEBULA_DIGITV 0x0201
+125 -47
drivers/media/dvb/dvb-usb/it913x.c
··· 64 64 struct it913x_state { 65 65 u8 id; 66 66 struct ite_config it913x_config; 67 + u8 pid_filter_onoff; 67 68 }; 68 69 69 70 struct ite_config it913x_config; ··· 260 259 261 260 static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) 262 261 { 262 + struct it913x_state *st = adap->dev->priv; 263 263 struct usb_device *udev = adap->dev->udev; 264 264 int ret; 265 265 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; 266 266 267 - if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) 268 - return -EAGAIN; 267 + mutex_lock(&adap->dev->i2c_mutex); 268 + 269 269 deb_info(1, "PID_C (%02x)", onoff); 270 270 271 - ret = it913x_wr_reg(udev, pro, PID_EN, onoff); 271 + ret = it913x_wr_reg(udev, pro, PID_EN, st->pid_filter_onoff); 272 272 273 273 mutex_unlock(&adap->dev->i2c_mutex); 274 274 return ret; ··· 278 276 static int it913x_pid_filter(struct dvb_usb_adapter *adap, 279 277 int index, u16 pid, int onoff) 280 278 { 279 + struct it913x_state *st = adap->dev->priv; 281 280 struct usb_device *udev = adap->dev->udev; 282 281 int ret; 283 282 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; 284 283 285 - if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) 286 - return -EAGAIN; 284 + mutex_lock(&adap->dev->i2c_mutex); 285 + 287 286 deb_info(1, "PID_F (%02x)", onoff); 288 287 289 288 ret = it913x_wr_reg(udev, pro, PID_LSB, (u8)(pid & 0xff)); ··· 294 291 ret |= it913x_wr_reg(udev, pro, PID_INX_EN, (u8)onoff); 295 292 296 293 ret |= it913x_wr_reg(udev, pro, PID_INX, (u8)(index & 0x1f)); 294 + 295 + if (udev->speed == USB_SPEED_HIGH && pid == 0x2000) { 296 + ret |= it913x_wr_reg(udev, pro, PID_EN, !onoff); 297 + st->pid_filter_onoff = !onoff; 298 + } else 299 + st->pid_filter_onoff = 300 + adap->fe_adap[adap->active_fe].pid_filtering; 297 301 298 302 mutex_unlock(&adap->dev->i2c_mutex); 299 303 return 0; ··· 326 316 int ret; 327 317 u32 reg; 328 318 u8 pro; 329 - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 330 - return -EAGAIN; 319 + 320 + mutex_lock(&d->i2c_mutex); 331 321 332 322 debug_data_snipet(1, "Message out", msg[0].buf); 333 323 deb_info(2, "num of messages %d address %02x", num, msg[0].addr); ··· 368 358 int ret; 369 359 u32 key; 370 360 /* Avoid conflict with frontends*/ 371 - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 372 - return -EAGAIN; 361 + mutex_lock(&d->i2c_mutex); 373 362 374 363 ret = it913x_io(d->udev, READ_LONG, PRO_LINK, CMD_IR_GET, 375 364 0, 0, &ibuf[0], sizeof(ibuf)); ··· 397 388 { 398 389 int sw; 399 390 /* auto switch */ 400 - if (le16_to_cpu(udev->descriptor.idProduct) == 401 - USB_PID_ITETECH_IT9135) 402 - sw = IT9135_V1_FW; 403 - else if (le16_to_cpu(udev->descriptor.idProduct) == 404 - USB_PID_ITETECH_IT9135_9005) 405 - sw = IT9135_V1_FW; 406 - else if (le16_to_cpu(udev->descriptor.idProduct) == 407 - USB_PID_ITETECH_IT9135_9006) { 408 - sw = IT9135_V2_FW; 409 - if (it913x_config.tuner_id_0 == 0) 410 - it913x_config.tuner_id_0 = IT9135_60; 411 - } else 391 + if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_KWORLD_2) 412 392 sw = IT9137_FW; 393 + else if (it913x_config.chip_ver == 1) 394 + sw = IT9135_V1_FW; 395 + else 396 + sw = IT9135_V2_FW; 413 397 414 398 /* force switch */ 415 399 if (dvb_usb_it913x_firmware != IT9135_AUTO) ··· 412 410 case IT9135_V1_FW: 413 411 it913x_config.firmware_ver = 1; 414 412 it913x_config.adc_x2 = 1; 413 + it913x_config.read_slevel = false; 415 414 props->firmware = fw_it9135_v1; 416 415 break; 417 416 case IT9135_V2_FW: 418 417 it913x_config.firmware_ver = 1; 419 418 it913x_config.adc_x2 = 1; 419 + it913x_config.read_slevel = false; 420 420 props->firmware = fw_it9135_v2; 421 + switch (it913x_config.tuner_id_0) { 422 + case IT9135_61: 423 + case IT9135_62: 424 + break; 425 + default: 426 + info("Unknown tuner ID applying default 0x60"); 427 + case IT9135_60: 428 + it913x_config.tuner_id_0 = IT9135_60; 429 + } 421 430 break; 422 431 case IT9137_FW: 423 432 default: 424 433 it913x_config.firmware_ver = 0; 425 434 it913x_config.adc_x2 = 0; 435 + it913x_config.read_slevel = true; 426 436 props->firmware = fw_it9137; 427 437 } 428 438 429 439 return 0; 440 + } 441 + 442 + static void it913x_select_remote(struct usb_device *udev, 443 + struct dvb_usb_device_properties *props) 444 + { 445 + switch (le16_to_cpu(udev->descriptor.idProduct)) { 446 + case USB_PID_ITETECH_IT9135_9005: 447 + props->rc.core.rc_codes = RC_MAP_IT913X_V2; 448 + return; 449 + default: 450 + props->rc.core.rc_codes = RC_MAP_IT913X_V1; 451 + } 452 + return; 430 453 } 431 454 432 455 #define TS_MPEG_PKT_SIZE 188 ··· 460 433 #define EP_HIGH 348 461 434 #define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE) 462 435 463 - static int it913x_identify_state(struct usb_device *udev, 464 - struct dvb_usb_device_properties *props, 465 - struct dvb_usb_device_description **desc, 466 - int *cold) 436 + static int it913x_select_config(struct usb_device *udev, 437 + struct dvb_usb_device_properties *props) 467 438 { 468 - int ret = 0, firm_no; 469 - u8 reg, remote; 439 + int ret = 0, reg; 440 + bool proprietary_ir = false; 470 441 471 - firm_no = it913x_return_status(udev); 442 + if (it913x_config.chip_ver == 0x02 443 + && it913x_config.chip_type == 0x9135) 444 + reg = it913x_read_reg(udev, 0x461d); 445 + else 446 + reg = it913x_read_reg(udev, 0x461b); 472 447 473 - /* checnk for dual mode */ 474 - it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5); 448 + if (reg < 0) 449 + return reg; 450 + 451 + if (reg == 0) { 452 + it913x_config.dual_mode = 0; 453 + it913x_config.tuner_id_0 = IT9135_38; 454 + proprietary_ir = true; 455 + } else { 456 + /* TS mode */ 457 + reg = it913x_read_reg(udev, 0x49c5); 458 + if (reg < 0) 459 + return reg; 460 + it913x_config.dual_mode = reg; 461 + 462 + /* IR mode type */ 463 + reg = it913x_read_reg(udev, 0x49ac); 464 + if (reg < 0) 465 + return reg; 466 + if (reg == 5) { 467 + info("Remote propriety (raw) mode"); 468 + proprietary_ir = true; 469 + } else if (reg == 1) { 470 + info("Remote HID mode NOT SUPPORTED"); 471 + proprietary_ir = false; 472 + props->rc.core.rc_codes = NULL; 473 + } else 474 + props->rc.core.rc_codes = NULL; 475 + 476 + /* Tuner_id */ 477 + reg = it913x_read_reg(udev, 0x49d0); 478 + if (reg < 0) 479 + return reg; 480 + it913x_config.tuner_id_0 = reg; 481 + } 482 + 483 + if (proprietary_ir) 484 + it913x_select_remote(udev, props); 475 485 476 486 if (udev->speed != USB_SPEED_HIGH) { 477 487 props->adapter[0].fe[0].pid_filter_count = 5; ··· 522 458 } else /* For replugging */ 523 459 if(props->adapter[0].fe[0].pid_filter_count == 5) 524 460 props->adapter[0].fe[0].pid_filter_count = 31; 525 - 526 - /* TODO different remotes */ 527 - remote = it913x_read_reg(udev, 0x49ac); /* Remote */ 528 - if (remote == 0) 529 - props->rc.core.rc_codes = NULL; 530 - 531 - /* TODO at the moment tuner_id is always assigned to 0x38 */ 532 - it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0); 533 - 534 - info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode 535 - , remote, it913x_config.tuner_id_0); 536 461 537 462 /* Select Stream Buffer Size and pid filter option*/ 538 463 if (pid_filter) { ··· 543 490 } else 544 491 props->num_adapters = 1; 545 492 493 + info("Dual mode=%x Tuner Type=%x", it913x_config.dual_mode, 494 + it913x_config.tuner_id_0); 495 + 546 496 ret = ite_firmware_select(udev, props); 497 + 498 + return ret; 499 + } 500 + 501 + static int it913x_identify_state(struct usb_device *udev, 502 + struct dvb_usb_device_properties *props, 503 + struct dvb_usb_device_description **desc, 504 + int *cold) 505 + { 506 + int ret = 0, firm_no; 507 + u8 reg; 508 + 509 + firm_no = it913x_return_status(udev); 510 + 511 + /* Read and select config */ 512 + ret = it913x_select_config(udev, props); 513 + if (ret < 0) 514 + return ret; 547 515 548 516 if (firm_no > 0) { 549 517 *cold = 0; ··· 612 538 613 539 static int it913x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 614 540 { 541 + struct it913x_state *st = adap->dev->priv; 615 542 int ret = 0; 616 543 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; 617 544 618 - if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) 619 - return -EAGAIN; 620 545 deb_info(1, "STM (%02x)", onoff); 621 546 622 - if (!onoff) 547 + if (!onoff) { 548 + mutex_lock(&adap->dev->i2c_mutex); 549 + 623 550 ret = it913x_wr_reg(adap->dev->udev, pro, PID_RST, 0x1); 624 551 552 + mutex_unlock(&adap->dev->i2c_mutex); 553 + st->pid_filter_onoff = 554 + adap->fe_adap[adap->active_fe].pid_filtering; 625 555 626 - mutex_unlock(&adap->dev->i2c_mutex); 556 + } 627 557 628 558 return ret; 629 559 } ··· 867 789 .rc_query = it913x_rc_query, 868 790 .rc_interval = IT913X_POLL, 869 791 .allowed_protos = RC_TYPE_NEC, 870 - .rc_codes = RC_MAP_MSI_DIGIVOX_III, 792 + .rc_codes = RC_MAP_IT913X_V1, 871 793 }, 872 794 .i2c_algo = &it913x_i2c_algo, 873 795 .num_device_descs = 5, ··· 901 823 902 824 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 903 825 MODULE_DESCRIPTION("it913x USB 2 Driver"); 904 - MODULE_VERSION("1.22"); 826 + MODULE_VERSION("1.27"); 905 827 MODULE_LICENSE("GPL");
+199 -90
drivers/media/dvb/dvb-usb/lmedm04.c
··· 77 77 #include "stv0299.h" 78 78 #include "dvb-pll.h" 79 79 #include "z0194a.h" 80 + #include "m88rs2000.h" 80 81 81 82 82 83 ··· 105 104 106 105 static int pid_filter; 107 106 module_param_named(pid, pid_filter, int, 0644); 108 - MODULE_PARM_DESC(pid, "set default 0=on 1=off"); 107 + MODULE_PARM_DESC(pid, "set default 0=default 1=off 2=on"); 109 108 110 109 111 110 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); ··· 114 113 #define TUNER_LG 0x1 115 114 #define TUNER_S7395 0x2 116 115 #define TUNER_S0194 0x3 116 + #define TUNER_RS2000 0x4 117 117 118 118 struct lme2510_state { 119 119 u8 id; ··· 123 121 u8 signal_level; 124 122 u8 signal_sn; 125 123 u8 time_key; 124 + u8 last_key; 125 + u8 key_timeout; 126 126 u8 i2c_talk_onoff; 127 127 u8 i2c_gate; 128 128 u8 i2c_tuner_gate_w; ··· 132 128 u8 i2c_tuner_addr; 133 129 u8 stream_on; 134 130 u8 pid_size; 131 + u8 pid_off; 135 132 void *buffer; 136 133 struct urb *lme_urb; 137 134 void *usb_buffer; ··· 183 178 /* the read/write capped at 64 */ 184 179 memcpy(buff, wbuf, (wlen < 64) ? wlen : 64); 185 180 186 - ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01)); 187 - 188 181 ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01); 189 - 190 - msleep(10); 191 - 192 - ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01)); 193 182 194 183 ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ? 195 184 rlen : 64 , 0x01); ··· 198 199 199 200 static int lme2510_stream_restart(struct dvb_usb_device *d) 200 201 { 201 - static u8 stream_on[] = LME_ST_ON_W; 202 + struct lme2510_state *st = d->priv; 203 + u8 all_pids[] = LME_ALL_PIDS; 204 + u8 stream_on[] = LME_ST_ON_W; 202 205 int ret; 203 - u8 rbuff[10]; 206 + u8 rbuff[1]; 207 + if (st->pid_off) 208 + ret = lme2510_usb_talk(d, all_pids, sizeof(all_pids), 209 + rbuff, sizeof(rbuff)); 204 210 /*Restart Stream Command*/ 205 211 ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on), 206 212 rbuff, sizeof(rbuff)); ··· 312 308 ((ibuf[2] & 0x01) << 0x03); 313 309 } 314 310 break; 311 + case TUNER_RS2000: 312 + if (ibuf[2] > 0) 313 + st->signal_lock = 0xff; 314 + else 315 + st->signal_lock = 0xf0; 316 + st->signal_level = ibuf[4]; 317 + st->signal_sn = ibuf[5]; 318 + st->time_key = ibuf[7]; 315 319 default: 316 320 break; 317 321 } ··· 371 359 static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) 372 360 { 373 361 struct lme2510_state *st = adap->dev->priv; 374 - static u8 clear_pid_reg[] = LME_CLEAR_PID; 362 + static u8 clear_pid_reg[] = LME_ALL_PIDS; 375 363 static u8 rbuf[1]; 376 364 int ret; 377 365 378 366 deb_info(1, "PID Clearing Filter"); 379 367 380 - ret = mutex_lock_interruptible(&adap->dev->i2c_mutex); 381 - if (ret < 0) 382 - return -EAGAIN; 368 + mutex_lock(&adap->dev->i2c_mutex); 383 369 384 - if (!onoff) 370 + if (!onoff) { 385 371 ret |= lme2510_usb_talk(adap->dev, clear_pid_reg, 386 372 sizeof(clear_pid_reg), rbuf, sizeof(rbuf)); 373 + st->pid_off = true; 374 + } else 375 + st->pid_off = false; 387 376 388 377 st->pid_size = 0; 389 378 ··· 402 389 pid, index, onoff); 403 390 404 391 if (onoff) { 405 - ret = mutex_lock_interruptible(&adap->dev->i2c_mutex); 406 - if (ret < 0) 407 - return -EAGAIN; 408 - ret |= lme2510_enable_pid(adap->dev, index, pid); 409 - mutex_unlock(&adap->dev->i2c_mutex); 392 + mutex_lock(&adap->dev->i2c_mutex); 393 + ret |= lme2510_enable_pid(adap->dev, index, pid); 394 + mutex_unlock(&adap->dev->i2c_mutex); 410 395 } 411 396 412 397 ··· 436 425 int ret = 0; 437 426 struct lme2510_state *st = d->priv; 438 427 439 - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 440 - return -EAGAIN; 441 - 442 428 if (st->i2c_talk_onoff == 1) { 443 429 444 430 ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen); ··· 464 456 st->i2c_talk_onoff = 0; 465 457 } 466 458 } 467 - if ((wbuf[3] != 0x6) & (wbuf[3] != 0x5)) 468 - msleep(5); 469 459 } 470 460 break; 471 461 case TUNER_S0194: ··· 478 472 } 479 473 } 480 474 break; 475 + case TUNER_RS2000: 481 476 default: 482 477 break; 483 478 } 484 479 } else { 480 + /* TODO rewrite this section */ 485 481 switch (st->tuner_config) { 486 482 case TUNER_LG: 487 483 switch (wbuf[3]) { ··· 567 559 break; 568 560 } 569 561 break; 562 + case TUNER_RS2000: 563 + switch (wbuf[3]) { 564 + case 0x8c: 565 + rbuf[0] = 0x55; 566 + rbuf[1] = 0xff; 567 + if (st->last_key == st->time_key) { 568 + st->key_timeout++; 569 + if (st->key_timeout > 5) 570 + rbuf[1] = 0; 571 + } else 572 + st->key_timeout = 0; 573 + st->last_key = st->time_key; 574 + break; 575 + default: 576 + lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen); 577 + st->i2c_talk_onoff = 1; 578 + break; 579 + } 570 580 default: 571 581 break; 572 582 } ··· 593 567 wbuf[3], rbuf[1]); 594 568 595 569 } 596 - 597 - mutex_unlock(&d->i2c_mutex); 598 570 599 571 return ret; 600 572 } ··· 607 583 int i, read, read_o; 608 584 u16 len; 609 585 u8 gate = st->i2c_gate; 586 + 587 + mutex_lock(&d->i2c_mutex); 610 588 611 589 if (gate == 0) 612 590 gate = 5; ··· 648 622 649 623 if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) { 650 624 deb_info(1, "i2c transfer failed."); 625 + mutex_unlock(&d->i2c_mutex); 651 626 return -EAGAIN; 652 627 } 653 628 ··· 661 634 } 662 635 } 663 636 } 637 + 638 + mutex_unlock(&d->i2c_mutex); 664 639 return i; 665 640 } 666 641 ··· 682 653 struct dvb_usb_device_description **desc, 683 654 int *cold) 684 655 { 685 - if (pid_filter > 0) 656 + if (pid_filter != 2) 686 657 props->adapter[0].fe[0].caps &= 687 658 ~DVB_USB_ADAP_NEED_PID_FILTERING; 688 659 *cold = 0; ··· 692 663 static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 693 664 { 694 665 struct lme2510_state *st = adap->dev->priv; 695 - static u8 clear_reg_3[] = LME_CLEAR_PID; 666 + static u8 clear_reg_3[] = LME_ALL_PIDS; 696 667 static u8 rbuf[1]; 697 668 int ret = 0, rlen = sizeof(rbuf); 698 669 ··· 704 675 else { 705 676 deb_info(1, "STM Steam Off"); 706 677 /* mutex is here only to avoid collision with I2C */ 707 - if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) 708 - return -EAGAIN; 678 + mutex_lock(&adap->dev->i2c_mutex); 709 679 710 680 ret = lme2510_usb_talk(adap->dev, clear_reg_3, 711 681 sizeof(clear_reg_3), rbuf, rlen); ··· 809 781 const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; 810 782 const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw"; 811 783 const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw"; 784 + const char fw_c_rs2000[] = "dvb-usb-lme2510c-rs2000.fw"; 812 785 const char fw_lg[] = "dvb-usb-lme2510-lg.fw"; 813 786 const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw"; 814 787 const char *fw_lme; 815 - int ret, cold_fw; 788 + int ret = 0, cold_fw; 816 789 817 790 cold = (cold > 0) ? (cold & 1) : 0; 818 791 819 792 cold_fw = !cold; 820 793 821 - if (le16_to_cpu(udev->descriptor.idProduct) == 0x1122) { 794 + switch (le16_to_cpu(udev->descriptor.idProduct)) { 795 + case 0x1122: 822 796 switch (dvb_usb_lme2510_firmware) { 823 797 default: 824 798 dvb_usb_lme2510_firmware = TUNER_S0194; ··· 843 813 cold_fw = 0; 844 814 break; 845 815 } 846 - } else { 816 + break; 817 + case 0x1120: 847 818 switch (dvb_usb_lme2510_firmware) { 848 819 default: 849 820 dvb_usb_lme2510_firmware = TUNER_S7395; ··· 873 842 cold_fw = 0; 874 843 break; 875 844 } 845 + break; 846 + case 0x22f0: 847 + fw_lme = fw_c_rs2000; 848 + ret = request_firmware(&fw, fw_lme, &udev->dev); 849 + dvb_usb_lme2510_firmware = TUNER_RS2000; 850 + break; 851 + default: 852 + fw_lme = fw_c_s7395; 876 853 } 854 + 877 855 878 856 if (cold_fw) { 879 857 info("FRM Loading %s file", fw_lme); ··· 946 906 .set_symbol_rate = sharp_z0194a_set_symbol_rate, 947 907 }; 948 908 909 + static int dm04_rs2000_set_ts_param(struct dvb_frontend *fe, 910 + int caller) 911 + { 912 + struct dvb_usb_adapter *adap = fe->dvb->priv; 913 + struct dvb_usb_device *d = adap->dev; 914 + struct lme2510_state *st = d->priv; 915 + 916 + mutex_lock(&d->i2c_mutex); 917 + if ((st->i2c_talk_onoff == 1) && (st->stream_on & 1)) { 918 + st->i2c_talk_onoff = 0; 919 + lme2510_stream_restart(d); 920 + } 921 + mutex_unlock(&d->i2c_mutex); 922 + 923 + return 0; 924 + } 925 + 926 + static struct m88rs2000_config m88rs2000_config = { 927 + .demod_addr = 0xd0, 928 + .tuner_addr = 0xc0, 929 + .set_ts_params = dm04_rs2000_set_ts_param, 930 + }; 931 + 949 932 static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, 950 933 fe_sec_voltage_t voltage) 951 934 { ··· 978 915 static u8 rbuf[1]; 979 916 int ret = 0, len = 3, rlen = 1; 980 917 981 - if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) 982 - return -EAGAIN; 918 + mutex_lock(&adap->dev->i2c_mutex); 983 919 984 920 switch (voltage) { 985 921 case SEC_VOLTAGE_18: ··· 999 937 return (ret < 0) ? -ENODEV : 0; 1000 938 } 1001 939 940 + static int dm04_rs2000_read_signal_strength(struct dvb_frontend *fe, 941 + u16 *strength) 942 + { 943 + struct dvb_usb_adapter *adap = fe->dvb->priv; 944 + struct lme2510_state *st = adap->dev->priv; 945 + 946 + *strength = (u16)((u32)st->signal_level * 0xffff / 0x7f); 947 + return 0; 948 + } 949 + 950 + static int dm04_rs2000_read_snr(struct dvb_frontend *fe, u16 *snr) 951 + { 952 + struct dvb_usb_adapter *adap = fe->dvb->priv; 953 + struct lme2510_state *st = adap->dev->priv; 954 + 955 + *snr = (u16)((u32)st->signal_sn * 0xffff / 0xff); 956 + return 0; 957 + } 958 + 1002 959 static int lme_name(struct dvb_usb_adapter *adap) 1003 960 { 1004 961 struct lme2510_state *st = adap->dev->priv; 1005 962 const char *desc = adap->dev->desc->name; 1006 963 char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395", 1007 - " SHARP:BS2F7HZ0194"}; 964 + " SHARP:BS2F7HZ0194", " RS2000"}; 1008 965 char *name = adap->fe_adap[0].fe->ops.info.name; 1009 966 1010 967 strlcpy(name, desc, 128); ··· 1039 958 int ret = 0; 1040 959 1041 960 st->i2c_talk_onoff = 1; 1042 - 1043 - st->i2c_gate = 4; 1044 - adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, 1045 - &adap->dev->i2c_adap); 1046 - 1047 - if (adap->fe_adap[0].fe) { 1048 - info("TUN Found Frontend TDA10086"); 1049 - st->i2c_tuner_gate_w = 4; 1050 - st->i2c_tuner_gate_r = 4; 1051 - st->i2c_tuner_addr = 0xc0; 1052 - st->tuner_config = TUNER_LG; 1053 - if (dvb_usb_lme2510_firmware != TUNER_LG) { 1054 - dvb_usb_lme2510_firmware = TUNER_LG; 1055 - ret = lme_firmware_switch(adap->dev->udev, 1); 961 + switch (le16_to_cpu(adap->dev->udev->descriptor.idProduct)) { 962 + case 0x1122: 963 + case 0x1120: 964 + st->i2c_gate = 4; 965 + adap->fe_adap[0].fe = dvb_attach(tda10086_attach, 966 + &tda10086_config, &adap->dev->i2c_adap); 967 + if (adap->fe_adap[0].fe) { 968 + info("TUN Found Frontend TDA10086"); 969 + st->i2c_tuner_gate_w = 4; 970 + st->i2c_tuner_gate_r = 4; 971 + st->i2c_tuner_addr = 0xc0; 972 + st->tuner_config = TUNER_LG; 973 + if (dvb_usb_lme2510_firmware != TUNER_LG) { 974 + dvb_usb_lme2510_firmware = TUNER_LG; 975 + ret = lme_firmware_switch(adap->dev->udev, 1); 976 + } 977 + break; 1056 978 } 1057 - goto end; 1058 - } 1059 979 1060 - st->i2c_gate = 4; 1061 - adap->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194_config, 980 + st->i2c_gate = 4; 981 + adap->fe_adap[0].fe = dvb_attach(stv0299_attach, 982 + &sharp_z0194_config, &adap->dev->i2c_adap); 983 + if (adap->fe_adap[0].fe) { 984 + info("FE Found Stv0299"); 985 + st->i2c_tuner_gate_w = 4; 986 + st->i2c_tuner_gate_r = 5; 987 + st->i2c_tuner_addr = 0xc0; 988 + st->tuner_config = TUNER_S0194; 989 + if (dvb_usb_lme2510_firmware != TUNER_S0194) { 990 + dvb_usb_lme2510_firmware = TUNER_S0194; 991 + ret = lme_firmware_switch(adap->dev->udev, 1); 992 + } 993 + break; 994 + } 995 + 996 + st->i2c_gate = 5; 997 + adap->fe_adap[0].fe = dvb_attach(stv0288_attach, &lme_config, 1062 998 &adap->dev->i2c_adap); 1063 - if (adap->fe_adap[0].fe) { 1064 - info("FE Found Stv0299"); 1065 - st->i2c_tuner_gate_w = 4; 1066 - st->i2c_tuner_gate_r = 5; 1067 - st->i2c_tuner_addr = 0xc0; 1068 - st->tuner_config = TUNER_S0194; 1069 - if (dvb_usb_lme2510_firmware != TUNER_S0194) { 1070 - dvb_usb_lme2510_firmware = TUNER_S0194; 1071 - ret = lme_firmware_switch(adap->dev->udev, 1); 999 + 1000 + if (adap->fe_adap[0].fe) { 1001 + info("FE Found Stv0288"); 1002 + st->i2c_tuner_gate_w = 4; 1003 + st->i2c_tuner_gate_r = 5; 1004 + st->i2c_tuner_addr = 0xc0; 1005 + st->tuner_config = TUNER_S7395; 1006 + if (dvb_usb_lme2510_firmware != TUNER_S7395) { 1007 + dvb_usb_lme2510_firmware = TUNER_S7395; 1008 + ret = lme_firmware_switch(adap->dev->udev, 1); 1009 + } 1010 + break; 1072 1011 } 1073 - goto end; 1012 + case 0x22f0: 1013 + st->i2c_gate = 5; 1014 + adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach, 1015 + &m88rs2000_config, &adap->dev->i2c_adap); 1016 + 1017 + if (adap->fe_adap[0].fe) { 1018 + info("FE Found M88RS2000"); 1019 + st->i2c_tuner_gate_w = 5; 1020 + st->i2c_tuner_gate_r = 5; 1021 + st->i2c_tuner_addr = 0xc0; 1022 + st->tuner_config = TUNER_RS2000; 1023 + adap->fe_adap[0].fe->ops.read_signal_strength = 1024 + dm04_rs2000_read_signal_strength; 1025 + adap->fe_adap[0].fe->ops.read_snr = 1026 + dm04_rs2000_read_snr; 1027 + } 1028 + break; 1074 1029 } 1075 1030 1076 - st->i2c_gate = 5; 1077 - adap->fe_adap[0].fe = dvb_attach(stv0288_attach, &lme_config, 1078 - &adap->dev->i2c_adap); 1079 - if (adap->fe_adap[0].fe) { 1080 - info("FE Found Stv0288"); 1081 - st->i2c_tuner_gate_w = 4; 1082 - st->i2c_tuner_gate_r = 5; 1083 - st->i2c_tuner_addr = 0xc0; 1084 - st->tuner_config = TUNER_S7395; 1085 - if (dvb_usb_lme2510_firmware != TUNER_S7395) { 1086 - dvb_usb_lme2510_firmware = TUNER_S7395; 1087 - ret = lme_firmware_switch(adap->dev->udev, 1); 1088 - } 1089 - } else { 1090 - info("DM04 Not Supported"); 1091 - return -ENODEV; 1031 + if (adap->fe_adap[0].fe == NULL) { 1032 + info("DM04/QQBOX Not Powered up or not Supported"); 1033 + return -ENODEV; 1092 1034 } 1093 1035 1094 - 1095 - end: if (ret) { 1036 + if (ret) { 1096 1037 if (adap->fe_adap[0].fe) { 1097 1038 dvb_frontend_detach(adap->fe_adap[0].fe); 1098 1039 adap->fe_adap[0].fe = NULL; ··· 1131 1028 static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) 1132 1029 { 1133 1030 struct lme2510_state *st = adap->dev->priv; 1134 - char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"}; 1031 + char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"}; 1135 1032 int ret = 0; 1136 1033 1137 1034 switch (st->tuner_config) { ··· 1149 1046 if (dvb_attach(dvb_pll_attach , adap->fe_adap[0].fe, 0xc0, 1150 1047 &adap->dev->i2c_adap, DVB_PLL_OPERA1)) 1151 1048 ret = st->tuner_config; 1049 + break; 1050 + case TUNER_RS2000: 1051 + ret = st->tuner_config; 1152 1052 break; 1153 1053 default: 1154 1054 break; ··· 1181 1075 static u8 lnb_on[] = LNB_ON; 1182 1076 static u8 lnb_off[] = LNB_OFF; 1183 1077 static u8 rbuf[1]; 1184 - int ret, len = 3, rlen = 1; 1078 + int ret = 0, len = 3, rlen = 1; 1185 1079 1186 - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 1187 - return -EAGAIN; 1080 + mutex_lock(&d->i2c_mutex); 1188 1081 1189 1082 if (onoff) 1190 1083 ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen); ··· 1241 1136 static struct usb_device_id lme2510_table[] = { 1242 1137 { USB_DEVICE(0x3344, 0x1122) }, /* LME2510 */ 1243 1138 { USB_DEVICE(0x3344, 0x1120) }, /* LME2510C */ 1139 + { USB_DEVICE(0x3344, 0x22f0) }, /* LME2510C RS2000 */ 1244 1140 {} /* Terminating entry */ 1245 1141 }; 1246 1142 ··· 1259 1153 DVB_USB_ADAP_NEED_PID_FILTERING| 1260 1154 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 1261 1155 .streaming_ctrl = lme2510_streaming_ctrl, 1262 - .pid_filter_count = 15, 1156 + .pid_filter_count = 32, 1263 1157 .pid_filter = lme2510_pid_filter, 1264 1158 .pid_filter_ctrl = lme2510_pid_filter_ctrl, 1265 1159 .frontend_attach = dm04_lme2510_frontend_attach, ··· 1310 1204 DVB_USB_ADAP_NEED_PID_FILTERING| 1311 1205 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 1312 1206 .streaming_ctrl = lme2510_streaming_ctrl, 1313 - .pid_filter_count = 15, 1207 + .pid_filter_count = 32, 1314 1208 .pid_filter = lme2510_pid_filter, 1315 1209 .pid_filter_ctrl = lme2510_pid_filter_ctrl, 1316 1210 .frontend_attach = dm04_lme2510_frontend_attach, ··· 1340 1234 .identify_state = lme2510_identify_state, 1341 1235 .i2c_algo = &lme2510_i2c_algo, 1342 1236 .generic_bulk_ctrl_endpoint = 0, 1343 - .num_device_descs = 1, 1237 + .num_device_descs = 2, 1344 1238 .devices = { 1345 1239 { "DM04_LME2510C_DVB-S", 1346 1240 { &lme2510_table[1], NULL }, 1241 + }, 1242 + { "DM04_LME2510C_DVB-S RS2000", 1243 + { &lme2510_table[2], NULL }, 1347 1244 }, 1348 1245 } 1349 1246 }; ··· 1404 1295 1405 1296 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 1406 1297 MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); 1407 - MODULE_VERSION("1.91"); 1298 + MODULE_VERSION("1.99"); 1408 1299 MODULE_LICENSE("GPL");
+1
drivers/media/dvb/dvb-usb/lmedm04.h
··· 41 41 #define LME_ST_ON_W {0x06, 0x00} 42 42 #define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0} 43 43 #define LME_ZERO_PID {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c} 44 + #define LME_ALL_PIDS {0x03, 0x06, 0x00, 0xff, 0x01, 0x1f, 0x20, 0x81} 44 45 45 46 /* LNB Voltage 46 47 * 07 XX XX
+2 -4
drivers/media/dvb/dvb-usb/mxl111sf.c
··· 351 351 adap_state->ep6_clockphase, 352 352 0, 0); 353 353 mxl_fail(ret); 354 + #if 0 354 355 } else { 355 356 ret = mxl111sf_disable_656_port(state); 356 357 mxl_fail(ret); 358 + #endif 357 359 } 358 - 359 - mxl111sf_read_reg(state, 0x12, &tmp); 360 - tmp &= ~0x04; 361 - mxl111sf_write_reg(state, 0x12, tmp); 362 360 363 361 return ret; 364 362 }
+982
drivers/media/dvb/dvb-usb/rtl28xxu.c
··· 1 + /* 2 + * Realtek RTL28xxU DVB USB driver 3 + * 4 + * Copyright (C) 2009 Antti Palosaari <crope@iki.fi> 5 + * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License along 18 + * with this program; if not, write to the Free Software Foundation, Inc., 19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 + */ 21 + 22 + #include "rtl28xxu.h" 23 + 24 + #include "rtl2830.h" 25 + 26 + #include "qt1010.h" 27 + #include "mt2060.h" 28 + #include "mxl5005s.h" 29 + 30 + /* debug */ 31 + static int dvb_usb_rtl28xxu_debug; 32 + module_param_named(debug, dvb_usb_rtl28xxu_debug, int, 0644); 33 + MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); 34 + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 35 + 36 + static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req) 37 + { 38 + int ret; 39 + unsigned int pipe; 40 + u8 requesttype; 41 + u8 *buf; 42 + 43 + buf = kmalloc(req->size, GFP_KERNEL); 44 + if (!buf) { 45 + ret = -ENOMEM; 46 + goto err; 47 + } 48 + 49 + if (req->index & CMD_WR_FLAG) { 50 + /* write */ 51 + memcpy(buf, req->data, req->size); 52 + requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); 53 + pipe = usb_sndctrlpipe(d->udev, 0); 54 + } else { 55 + /* read */ 56 + requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); 57 + pipe = usb_rcvctrlpipe(d->udev, 0); 58 + } 59 + 60 + ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value, 61 + req->index, buf, req->size, 1000); 62 + if (ret > 0) 63 + ret = 0; 64 + 65 + deb_dump(0, requesttype, req->value, req->index, buf, req->size, 66 + deb_xfer); 67 + 68 + /* read request, copy returned data to return buf */ 69 + if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) 70 + memcpy(req->data, buf, req->size); 71 + 72 + kfree(buf); 73 + 74 + if (ret) 75 + goto err; 76 + 77 + return ret; 78 + err: 79 + deb_info("%s: failed=%d\n", __func__, ret); 80 + return ret; 81 + } 82 + 83 + static int rtl2831_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len) 84 + { 85 + struct rtl28xxu_req req; 86 + 87 + if (reg < 0x3000) 88 + req.index = CMD_USB_WR; 89 + else if (reg < 0x4000) 90 + req.index = CMD_SYS_WR; 91 + else 92 + req.index = CMD_IR_WR; 93 + 94 + req.value = reg; 95 + req.size = len; 96 + req.data = val; 97 + 98 + return rtl28xxu_ctrl_msg(d, &req); 99 + } 100 + 101 + static int rtl2831_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len) 102 + { 103 + struct rtl28xxu_req req; 104 + 105 + if (reg < 0x3000) 106 + req.index = CMD_USB_RD; 107 + else if (reg < 0x4000) 108 + req.index = CMD_SYS_RD; 109 + else 110 + req.index = CMD_IR_RD; 111 + 112 + req.value = reg; 113 + req.size = len; 114 + req.data = val; 115 + 116 + return rtl28xxu_ctrl_msg(d, &req); 117 + } 118 + 119 + static int rtl2831_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val) 120 + { 121 + return rtl2831_wr_regs(d, reg, &val, 1); 122 + } 123 + 124 + static int rtl2831_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val) 125 + { 126 + return rtl2831_rd_regs(d, reg, val, 1); 127 + } 128 + 129 + /* I2C */ 130 + static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], 131 + int num) 132 + { 133 + int ret; 134 + struct dvb_usb_device *d = i2c_get_adapdata(adap); 135 + struct rtl28xxu_priv *priv = d->priv; 136 + struct rtl28xxu_req req; 137 + 138 + /* 139 + * It is not known which are real I2C bus xfer limits, but testing 140 + * with RTL2831U + MT2060 gives max RD 24 and max WR 22 bytes. 141 + * TODO: find out RTL2832U lens 142 + */ 143 + 144 + /* 145 + * I2C adapter logic looks rather complicated due to fact it handles 146 + * three different access methods. Those methods are; 147 + * 1) integrated demod access 148 + * 2) old I2C access 149 + * 3) new I2C access 150 + * 151 + * Used method is selected in order 1, 2, 3. Method 3 can handle all 152 + * requests but there is two reasons why not use it always; 153 + * 1) It is most expensive, usually two USB messages are needed 154 + * 2) At least RTL2831U does not support it 155 + * 156 + * Method 3 is needed in case of I2C write+read (typical register read) 157 + * where write is more than one byte. 158 + */ 159 + 160 + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 161 + return -EAGAIN; 162 + 163 + if (num == 2 && !(msg[0].flags & I2C_M_RD) && 164 + (msg[1].flags & I2C_M_RD)) { 165 + if (msg[0].len > 24 || msg[1].len > 24) { 166 + /* TODO: check msg[0].len max */ 167 + ret = -EOPNOTSUPP; 168 + goto err_mutex_unlock; 169 + } else if (msg[0].addr == 0x10) { 170 + /* method 1 - integrated demod */ 171 + req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); 172 + req.index = CMD_DEMOD_RD | priv->page; 173 + req.size = msg[1].len; 174 + req.data = &msg[1].buf[0]; 175 + ret = rtl28xxu_ctrl_msg(d, &req); 176 + } else if (msg[0].len < 2) { 177 + /* method 2 - old I2C */ 178 + req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); 179 + req.index = CMD_I2C_RD; 180 + req.size = msg[1].len; 181 + req.data = &msg[1].buf[0]; 182 + ret = rtl28xxu_ctrl_msg(d, &req); 183 + } else { 184 + /* method 3 - new I2C */ 185 + req.value = (msg[0].addr << 1); 186 + req.index = CMD_I2C_DA_WR; 187 + req.size = msg[0].len; 188 + req.data = msg[0].buf; 189 + ret = rtl28xxu_ctrl_msg(d, &req); 190 + if (ret) 191 + goto err_mutex_unlock; 192 + 193 + req.value = (msg[0].addr << 1); 194 + req.index = CMD_I2C_DA_RD; 195 + req.size = msg[1].len; 196 + req.data = msg[1].buf; 197 + ret = rtl28xxu_ctrl_msg(d, &req); 198 + } 199 + } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) { 200 + if (msg[0].len > 22) { 201 + /* TODO: check msg[0].len max */ 202 + ret = -EOPNOTSUPP; 203 + goto err_mutex_unlock; 204 + } else if (msg[0].addr == 0x10) { 205 + /* method 1 - integrated demod */ 206 + if (msg[0].buf[0] == 0x00) { 207 + /* save demod page for later demod access */ 208 + priv->page = msg[0].buf[1]; 209 + ret = 0; 210 + } else { 211 + req.value = (msg[0].buf[0] << 8) | 212 + (msg[0].addr << 1); 213 + req.index = CMD_DEMOD_WR | priv->page; 214 + req.size = msg[0].len-1; 215 + req.data = &msg[0].buf[1]; 216 + ret = rtl28xxu_ctrl_msg(d, &req); 217 + } 218 + } else if (msg[0].len < 23) { 219 + /* method 2 - old I2C */ 220 + req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); 221 + req.index = CMD_I2C_WR; 222 + req.size = msg[0].len-1; 223 + req.data = &msg[0].buf[1]; 224 + ret = rtl28xxu_ctrl_msg(d, &req); 225 + } else { 226 + /* method 3 - new I2C */ 227 + req.value = (msg[0].addr << 1); 228 + req.index = CMD_I2C_DA_WR; 229 + req.size = msg[0].len; 230 + req.data = msg[0].buf; 231 + ret = rtl28xxu_ctrl_msg(d, &req); 232 + } 233 + } else { 234 + ret = -EINVAL; 235 + } 236 + 237 + err_mutex_unlock: 238 + mutex_unlock(&d->i2c_mutex); 239 + 240 + return ret ? ret : num; 241 + } 242 + 243 + static u32 rtl28xxu_i2c_func(struct i2c_adapter *adapter) 244 + { 245 + return I2C_FUNC_I2C; 246 + } 247 + 248 + static struct i2c_algorithm rtl28xxu_i2c_algo = { 249 + .master_xfer = rtl28xxu_i2c_xfer, 250 + .functionality = rtl28xxu_i2c_func, 251 + }; 252 + 253 + static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = { 254 + .i2c_addr = 0x10, /* 0x20 */ 255 + .xtal = 28800000, 256 + .ts_mode = 0, 257 + .spec_inv = 1, 258 + .if_dvbt = 36150000, 259 + .vtop = 0x20, 260 + .krf = 0x04, 261 + .agc_targ_val = 0x2d, 262 + 263 + }; 264 + 265 + static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = { 266 + .i2c_addr = 0x10, /* 0x20 */ 267 + .xtal = 28800000, 268 + .ts_mode = 0, 269 + .spec_inv = 1, 270 + .if_dvbt = 36125000, 271 + .vtop = 0x20, 272 + .krf = 0x04, 273 + .agc_targ_val = 0x2d, 274 + }; 275 + 276 + static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = { 277 + .i2c_addr = 0x10, /* 0x20 */ 278 + .xtal = 28800000, 279 + .ts_mode = 0, 280 + .spec_inv = 0, 281 + .if_dvbt = 4570000, 282 + .vtop = 0x3f, 283 + .krf = 0x04, 284 + .agc_targ_val = 0x3e, 285 + }; 286 + 287 + static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap) 288 + { 289 + int ret; 290 + struct rtl28xxu_priv *priv = adap->dev->priv; 291 + u8 buf[1]; 292 + struct rtl2830_config *rtl2830_config; 293 + /* open RTL2831U/RTL2830 I2C gate */ 294 + struct rtl28xxu_req req_gate = { 0x0120, 0x0011, 0x0001, "\x08" }; 295 + /* for MT2060 tuner probe */ 296 + struct rtl28xxu_req req_mt2060 = { 0x00c0, CMD_I2C_RD, 1, buf }; 297 + /* for QT1010 tuner probe */ 298 + struct rtl28xxu_req req_qt1010 = { 0x0fc4, CMD_I2C_RD, 1, buf }; 299 + 300 + deb_info("%s:\n", __func__); 301 + 302 + /* 303 + * RTL2831U GPIOs 304 + * ========================================================= 305 + * GPIO0 | tuner#0 | 0 off | 1 on | MXL5005S (?) 306 + * GPIO2 | LED | 0 off | 1 on | 307 + * GPIO4 | tuner#1 | 0 on | 1 off | MT2060 308 + */ 309 + 310 + /* GPIO direction */ 311 + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a); 312 + if (ret) 313 + goto err; 314 + 315 + /* enable as output GPIO0, GPIO2, GPIO4 */ 316 + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15); 317 + if (ret) 318 + goto err; 319 + 320 + /* 321 + * Probe used tuner. We need to know used tuner before demod attach 322 + * since there is some demod params needed to set according to tuner. 323 + */ 324 + 325 + /* open demod I2C gate */ 326 + ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate); 327 + if (ret) 328 + goto err; 329 + 330 + /* check QT1010 ID(?) register; reg=0f val=2c */ 331 + ret = rtl28xxu_ctrl_msg(adap->dev, &req_qt1010); 332 + if (ret == 0 && buf[0] == 0x2c) { 333 + priv->tuner = TUNER_RTL2830_QT1010; 334 + rtl2830_config = &rtl28xxu_rtl2830_qt1010_config; 335 + deb_info("%s: QT1010\n", __func__); 336 + goto found; 337 + } else { 338 + deb_info("%s: QT1010 probe failed=%d - %02x\n", 339 + __func__, ret, buf[0]); 340 + } 341 + 342 + /* open demod I2C gate */ 343 + ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate); 344 + if (ret) 345 + goto err; 346 + 347 + /* check MT2060 ID register; reg=00 val=63 */ 348 + ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2060); 349 + if (ret == 0 && buf[0] == 0x63) { 350 + priv->tuner = TUNER_RTL2830_MT2060; 351 + rtl2830_config = &rtl28xxu_rtl2830_mt2060_config; 352 + deb_info("%s: MT2060\n", __func__); 353 + goto found; 354 + } else { 355 + deb_info("%s: MT2060 probe failed=%d - %02x\n", 356 + __func__, ret, buf[0]); 357 + } 358 + 359 + /* assume MXL5005S */ 360 + ret = 0; 361 + priv->tuner = TUNER_RTL2830_MXL5005S; 362 + rtl2830_config = &rtl28xxu_rtl2830_mxl5005s_config; 363 + deb_info("%s: MXL5005S\n", __func__); 364 + goto found; 365 + 366 + found: 367 + /* attach demodulator */ 368 + adap->fe_adap[0].fe = dvb_attach(rtl2830_attach, rtl2830_config, 369 + &adap->dev->i2c_adap); 370 + if (adap->fe_adap[0].fe == NULL) { 371 + ret = -ENODEV; 372 + goto err; 373 + } 374 + 375 + return ret; 376 + err: 377 + deb_info("%s: failed=%d\n", __func__, ret); 378 + return ret; 379 + } 380 + 381 + static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) 382 + { 383 + int ret; 384 + struct rtl28xxu_priv *priv = adap->dev->priv; 385 + u8 buf[1]; 386 + /* open RTL2832U/RTL2832 I2C gate */ 387 + struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"}; 388 + /* close RTL2832U/RTL2832 I2C gate */ 389 + struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"}; 390 + /* for FC2580 tuner probe */ 391 + struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf}; 392 + 393 + deb_info("%s:\n", __func__); 394 + 395 + /* GPIO direction */ 396 + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a); 397 + if (ret) 398 + goto err; 399 + 400 + /* enable as output GPIO0, GPIO2, GPIO4 */ 401 + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15); 402 + if (ret) 403 + goto err; 404 + 405 + ret = rtl2831_wr_reg(adap->dev, SYS_DEMOD_CTL, 0xe8); 406 + if (ret) 407 + goto err; 408 + 409 + /* 410 + * Probe used tuner. We need to know used tuner before demod attach 411 + * since there is some demod params needed to set according to tuner. 412 + */ 413 + 414 + /* open demod I2C gate */ 415 + ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_open); 416 + if (ret) 417 + goto err; 418 + 419 + /* check FC2580 ID register; reg=01 val=56 */ 420 + ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc2580); 421 + if (ret == 0 && buf[0] == 0x56) { 422 + priv->tuner = TUNER_RTL2832_FC2580; 423 + deb_info("%s: FC2580\n", __func__); 424 + goto found; 425 + } else { 426 + deb_info("%s: FC2580 probe failed=%d - %02x\n", 427 + __func__, ret, buf[0]); 428 + } 429 + 430 + /* close demod I2C gate */ 431 + ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close); 432 + if (ret) 433 + goto err; 434 + 435 + /* tuner not found */ 436 + ret = -ENODEV; 437 + goto err; 438 + 439 + found: 440 + /* close demod I2C gate */ 441 + ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close); 442 + if (ret) 443 + goto err; 444 + 445 + /* attach demodulator */ 446 + /* TODO: */ 447 + 448 + return ret; 449 + err: 450 + deb_info("%s: failed=%d\n", __func__, ret); 451 + return ret; 452 + } 453 + 454 + static struct qt1010_config rtl28xxu_qt1010_config = { 455 + .i2c_address = 0x62, /* 0xc4 */ 456 + }; 457 + 458 + static struct mt2060_config rtl28xxu_mt2060_config = { 459 + .i2c_address = 0x60, /* 0xc0 */ 460 + .clock_out = 0, 461 + }; 462 + 463 + static struct mxl5005s_config rtl28xxu_mxl5005s_config = { 464 + .i2c_address = 0x63, /* 0xc6 */ 465 + .if_freq = IF_FREQ_4570000HZ, 466 + .xtal_freq = CRYSTAL_FREQ_16000000HZ, 467 + .agc_mode = MXL_SINGLE_AGC, 468 + .tracking_filter = MXL_TF_C_H, 469 + .rssi_enable = MXL_RSSI_ENABLE, 470 + .cap_select = MXL_CAP_SEL_ENABLE, 471 + .div_out = MXL_DIV_OUT_4, 472 + .clock_out = MXL_CLOCK_OUT_DISABLE, 473 + .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, 474 + .top = MXL5005S_TOP_25P2, 475 + .mod_mode = MXL_DIGITAL_MODE, 476 + .if_mode = MXL_ZERO_IF, 477 + .AgcMasterByte = 0x00, 478 + }; 479 + 480 + static int rtl2831u_tuner_attach(struct dvb_usb_adapter *adap) 481 + { 482 + int ret; 483 + struct rtl28xxu_priv *priv = adap->dev->priv; 484 + struct i2c_adapter *rtl2830_tuner_i2c; 485 + struct dvb_frontend *fe; 486 + 487 + deb_info("%s:\n", __func__); 488 + 489 + /* use rtl2830 driver I2C adapter, for more info see rtl2830 driver */ 490 + rtl2830_tuner_i2c = rtl2830_get_tuner_i2c_adapter(adap->fe_adap[0].fe); 491 + 492 + switch (priv->tuner) { 493 + case TUNER_RTL2830_QT1010: 494 + fe = dvb_attach(qt1010_attach, adap->fe_adap[0].fe, 495 + rtl2830_tuner_i2c, &rtl28xxu_qt1010_config); 496 + break; 497 + case TUNER_RTL2830_MT2060: 498 + fe = dvb_attach(mt2060_attach, adap->fe_adap[0].fe, 499 + rtl2830_tuner_i2c, &rtl28xxu_mt2060_config, 500 + 1220); 501 + break; 502 + case TUNER_RTL2830_MXL5005S: 503 + fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, 504 + rtl2830_tuner_i2c, &rtl28xxu_mxl5005s_config); 505 + break; 506 + default: 507 + fe = NULL; 508 + err("unknown tuner=%d", priv->tuner); 509 + } 510 + 511 + if (fe == NULL) { 512 + ret = -ENODEV; 513 + goto err; 514 + } 515 + 516 + return 0; 517 + err: 518 + deb_info("%s: failed=%d\n", __func__, ret); 519 + return ret; 520 + } 521 + 522 + static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) 523 + { 524 + int ret; 525 + struct rtl28xxu_priv *priv = adap->dev->priv; 526 + struct dvb_frontend *fe; 527 + 528 + deb_info("%s:\n", __func__); 529 + 530 + switch (priv->tuner) { 531 + case TUNER_RTL2832_FC2580: 532 + /* TODO: */ 533 + fe = NULL; 534 + break; 535 + default: 536 + fe = NULL; 537 + err("unknown tuner=%d", priv->tuner); 538 + } 539 + 540 + if (fe == NULL) { 541 + ret = -ENODEV; 542 + goto err; 543 + } 544 + 545 + return 0; 546 + err: 547 + deb_info("%s: failed=%d\n", __func__, ret); 548 + return ret; 549 + } 550 + 551 + static int rtl28xxu_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff) 552 + { 553 + int ret; 554 + u8 buf[2], gpio; 555 + 556 + deb_info("%s: onoff=%d\n", __func__, onoff); 557 + 558 + ret = rtl2831_rd_reg(adap->dev, SYS_GPIO_OUT_VAL, &gpio); 559 + if (ret) 560 + goto err; 561 + 562 + if (onoff) { 563 + buf[0] = 0x00; 564 + buf[1] = 0x00; 565 + gpio |= 0x04; /* LED on */ 566 + } else { 567 + buf[0] = 0x10; /* stall EPA */ 568 + buf[1] = 0x02; /* reset EPA */ 569 + gpio &= (~0x04); /* LED off */ 570 + } 571 + 572 + ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio); 573 + if (ret) 574 + goto err; 575 + 576 + ret = rtl2831_wr_regs(adap->dev, USB_EPA_CTL, buf, 2); 577 + if (ret) 578 + goto err; 579 + 580 + return ret; 581 + err: 582 + deb_info("%s: failed=%d\n", __func__, ret); 583 + return ret; 584 + } 585 + 586 + static int rtl28xxu_power_ctrl(struct dvb_usb_device *d, int onoff) 587 + { 588 + int ret; 589 + u8 gpio, sys0; 590 + 591 + deb_info("%s: onoff=%d\n", __func__, onoff); 592 + 593 + /* demod adc */ 594 + ret = rtl2831_rd_reg(d, SYS_SYS0, &sys0); 595 + if (ret) 596 + goto err; 597 + 598 + /* tuner power, read GPIOs */ 599 + ret = rtl2831_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio); 600 + if (ret) 601 + goto err; 602 + 603 + deb_info("%s: RD SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio); 604 + 605 + if (onoff) { 606 + gpio |= 0x01; /* GPIO0 = 1 */ 607 + gpio &= (~0x10); /* GPIO4 = 0 */ 608 + sys0 = sys0 & 0x0f; 609 + sys0 |= 0xe0; 610 + } else { 611 + gpio &= (~0x01); /* GPIO0 = 0 */ 612 + gpio |= 0x10; /* GPIO4 = 1 */ 613 + sys0 = sys0 & (~0xc0); 614 + } 615 + 616 + deb_info("%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio); 617 + 618 + /* demod adc */ 619 + ret = rtl2831_wr_reg(d, SYS_SYS0, sys0); 620 + if (ret) 621 + goto err; 622 + 623 + /* tuner power, write GPIOs */ 624 + ret = rtl2831_wr_reg(d, SYS_GPIO_OUT_VAL, gpio); 625 + if (ret) 626 + goto err; 627 + 628 + return ret; 629 + err: 630 + deb_info("%s: failed=%d\n", __func__, ret); 631 + return ret; 632 + } 633 + 634 + static int rtl2831u_rc_query(struct dvb_usb_device *d) 635 + { 636 + int ret, i; 637 + struct rtl28xxu_priv *priv = d->priv; 638 + u8 buf[5]; 639 + u32 rc_code; 640 + struct rtl28xxu_reg_val rc_nec_tab[] = { 641 + { 0x3033, 0x80 }, 642 + { 0x3020, 0x43 }, 643 + { 0x3021, 0x16 }, 644 + { 0x3022, 0x16 }, 645 + { 0x3023, 0x5a }, 646 + { 0x3024, 0x2d }, 647 + { 0x3025, 0x16 }, 648 + { 0x3026, 0x01 }, 649 + { 0x3028, 0xb0 }, 650 + { 0x3029, 0x04 }, 651 + { 0x302c, 0x88 }, 652 + { 0x302e, 0x13 }, 653 + { 0x3030, 0xdf }, 654 + { 0x3031, 0x05 }, 655 + }; 656 + 657 + /* init remote controller */ 658 + if (!priv->rc_active) { 659 + for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) { 660 + ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg, 661 + rc_nec_tab[i].val); 662 + if (ret) 663 + goto err; 664 + } 665 + priv->rc_active = true; 666 + } 667 + 668 + ret = rtl2831_rd_regs(d, SYS_IRRC_RP, buf, 5); 669 + if (ret) 670 + goto err; 671 + 672 + if (buf[4] & 0x01) { 673 + if (buf[2] == (u8) ~buf[3]) { 674 + if (buf[0] == (u8) ~buf[1]) { 675 + /* NEC standard (16 bit) */ 676 + rc_code = buf[0] << 8 | buf[2]; 677 + } else { 678 + /* NEC extended (24 bit) */ 679 + rc_code = buf[0] << 16 | 680 + buf[1] << 8 | buf[2]; 681 + } 682 + } else { 683 + /* NEC full (32 bit) */ 684 + rc_code = buf[0] << 24 | buf[1] << 16 | 685 + buf[2] << 8 | buf[3]; 686 + } 687 + 688 + rc_keydown(d->rc_dev, rc_code, 0); 689 + 690 + ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1); 691 + if (ret) 692 + goto err; 693 + 694 + /* repeated intentionally to avoid extra keypress */ 695 + ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1); 696 + if (ret) 697 + goto err; 698 + } 699 + 700 + return ret; 701 + err: 702 + deb_info("%s: failed=%d\n", __func__, ret); 703 + return ret; 704 + } 705 + 706 + static int rtl2832u_rc_query(struct dvb_usb_device *d) 707 + { 708 + int ret, i; 709 + struct rtl28xxu_priv *priv = d->priv; 710 + u8 buf[128]; 711 + int len; 712 + struct rtl28xxu_reg_val rc_nec_tab[] = { 713 + { IR_RX_CTRL, 0x20 }, 714 + { IR_RX_BUF_CTRL, 0x80 }, 715 + { IR_RX_IF, 0xff }, 716 + { IR_RX_IE, 0xff }, 717 + { IR_MAX_DURATION0, 0xd0 }, 718 + { IR_MAX_DURATION1, 0x07 }, 719 + { IR_IDLE_LEN0, 0xc0 }, 720 + { IR_IDLE_LEN1, 0x00 }, 721 + { IR_GLITCH_LEN, 0x03 }, 722 + { IR_RX_CLK, 0x09 }, 723 + { IR_RX_CFG, 0x1c }, 724 + { IR_MAX_H_TOL_LEN, 0x1e }, 725 + { IR_MAX_L_TOL_LEN, 0x1e }, 726 + { IR_RX_CTRL, 0x80 }, 727 + }; 728 + 729 + /* init remote controller */ 730 + if (!priv->rc_active) { 731 + for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) { 732 + ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg, 733 + rc_nec_tab[i].val); 734 + if (ret) 735 + goto err; 736 + } 737 + priv->rc_active = true; 738 + } 739 + 740 + ret = rtl2831_rd_reg(d, IR_RX_IF, &buf[0]); 741 + if (ret) 742 + goto err; 743 + 744 + if (buf[0] != 0x83) 745 + goto exit; 746 + 747 + ret = rtl2831_rd_reg(d, IR_RX_BC, &buf[0]); 748 + if (ret) 749 + goto err; 750 + 751 + len = buf[0]; 752 + ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len); 753 + 754 + /* TODO: pass raw IR to Kernel IR decoder */ 755 + 756 + ret = rtl2831_wr_reg(d, IR_RX_IF, 0x03); 757 + ret = rtl2831_wr_reg(d, IR_RX_BUF_CTRL, 0x80); 758 + ret = rtl2831_wr_reg(d, IR_RX_CTRL, 0x80); 759 + 760 + exit: 761 + return ret; 762 + err: 763 + deb_info("%s: failed=%d\n", __func__, ret); 764 + return ret; 765 + } 766 + 767 + enum rtl28xxu_usb_table_entry { 768 + RTL2831U_0BDA_2831, 769 + RTL2831U_14AA_0160, 770 + RTL2831U_14AA_0161, 771 + }; 772 + 773 + static struct usb_device_id rtl28xxu_table[] = { 774 + /* RTL2831U */ 775 + [RTL2831U_0BDA_2831] = { 776 + USB_DEVICE(USB_VID_REALTEK, USB_PID_REALTEK_RTL2831U)}, 777 + [RTL2831U_14AA_0160] = { 778 + USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT)}, 779 + [RTL2831U_14AA_0161] = { 780 + USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2)}, 781 + 782 + /* RTL2832U */ 783 + {} /* terminating entry */ 784 + }; 785 + 786 + MODULE_DEVICE_TABLE(usb, rtl28xxu_table); 787 + 788 + static struct dvb_usb_device_properties rtl28xxu_properties[] = { 789 + { 790 + .caps = DVB_USB_IS_AN_I2C_ADAPTER, 791 + 792 + .usb_ctrl = DEVICE_SPECIFIC, 793 + .no_reconnect = 1, 794 + 795 + .size_of_priv = sizeof(struct rtl28xxu_priv), 796 + 797 + .num_adapters = 1, 798 + .adapter = { 799 + { 800 + .num_frontends = 1, 801 + .fe = { 802 + { 803 + .frontend_attach = rtl2831u_frontend_attach, 804 + .tuner_attach = rtl2831u_tuner_attach, 805 + .streaming_ctrl = rtl28xxu_streaming_ctrl, 806 + .stream = { 807 + .type = USB_BULK, 808 + .count = 6, 809 + .endpoint = 0x81, 810 + .u = { 811 + .bulk = { 812 + .buffersize = 8*512, 813 + } 814 + } 815 + } 816 + } 817 + } 818 + } 819 + }, 820 + 821 + .power_ctrl = rtl28xxu_power_ctrl, 822 + 823 + .rc.core = { 824 + .protocol = RC_TYPE_NEC, 825 + .module_name = "rtl28xxu", 826 + .rc_query = rtl2831u_rc_query, 827 + .rc_interval = 400, 828 + .allowed_protos = RC_TYPE_NEC, 829 + .rc_codes = RC_MAP_EMPTY, 830 + }, 831 + 832 + .i2c_algo = &rtl28xxu_i2c_algo, 833 + 834 + .num_device_descs = 2, 835 + .devices = { 836 + { 837 + .name = "Realtek RTL2831U reference design", 838 + .warm_ids = { 839 + &rtl28xxu_table[RTL2831U_0BDA_2831], 840 + }, 841 + }, 842 + { 843 + .name = "Freecom USB2.0 DVB-T", 844 + .warm_ids = { 845 + &rtl28xxu_table[RTL2831U_14AA_0160], 846 + &rtl28xxu_table[RTL2831U_14AA_0161], 847 + }, 848 + }, 849 + } 850 + }, 851 + { 852 + .caps = DVB_USB_IS_AN_I2C_ADAPTER, 853 + 854 + .usb_ctrl = DEVICE_SPECIFIC, 855 + .no_reconnect = 1, 856 + 857 + .size_of_priv = sizeof(struct rtl28xxu_priv), 858 + 859 + .num_adapters = 1, 860 + .adapter = { 861 + { 862 + .num_frontends = 1, 863 + .fe = { 864 + { 865 + .frontend_attach = rtl2832u_frontend_attach, 866 + .tuner_attach = rtl2832u_tuner_attach, 867 + .streaming_ctrl = rtl28xxu_streaming_ctrl, 868 + .stream = { 869 + .type = USB_BULK, 870 + .count = 6, 871 + .endpoint = 0x81, 872 + .u = { 873 + .bulk = { 874 + .buffersize = 8*512, 875 + } 876 + } 877 + } 878 + } 879 + } 880 + } 881 + }, 882 + 883 + .power_ctrl = rtl28xxu_power_ctrl, 884 + 885 + .rc.core = { 886 + .protocol = RC_TYPE_NEC, 887 + .module_name = "rtl28xxu", 888 + .rc_query = rtl2832u_rc_query, 889 + .rc_interval = 400, 890 + .allowed_protos = RC_TYPE_NEC, 891 + .rc_codes = RC_MAP_EMPTY, 892 + }, 893 + 894 + .i2c_algo = &rtl28xxu_i2c_algo, 895 + 896 + .num_device_descs = 0, /* disabled as no support for RTL2832 */ 897 + .devices = { 898 + { 899 + .name = "Realtek RTL2832U reference design", 900 + }, 901 + } 902 + }, 903 + 904 + }; 905 + 906 + static int rtl28xxu_probe(struct usb_interface *intf, 907 + const struct usb_device_id *id) 908 + { 909 + int ret, i; 910 + int properties_count = ARRAY_SIZE(rtl28xxu_properties); 911 + struct dvb_usb_device *d; 912 + 913 + deb_info("%s: interface=%d\n", __func__, 914 + intf->cur_altsetting->desc.bInterfaceNumber); 915 + 916 + if (intf->cur_altsetting->desc.bInterfaceNumber != 0) 917 + return 0; 918 + 919 + for (i = 0; i < properties_count; i++) { 920 + ret = dvb_usb_device_init(intf, &rtl28xxu_properties[i], 921 + THIS_MODULE, &d, adapter_nr); 922 + if (ret == 0 || ret != -ENODEV) 923 + break; 924 + } 925 + 926 + if (ret) 927 + goto err; 928 + 929 + /* init USB endpoints */ 930 + ret = rtl2831_wr_reg(d, USB_SYSCTL_0, 0x09); 931 + if (ret) 932 + goto err; 933 + 934 + ret = rtl2831_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4); 935 + if (ret) 936 + goto err; 937 + 938 + ret = rtl2831_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4); 939 + if (ret) 940 + goto err; 941 + 942 + return ret; 943 + err: 944 + deb_info("%s: failed=%d\n", __func__, ret); 945 + return ret; 946 + } 947 + 948 + static struct usb_driver rtl28xxu_driver = { 949 + .name = "dvb_usb_rtl28xxu", 950 + .probe = rtl28xxu_probe, 951 + .disconnect = dvb_usb_device_exit, 952 + .id_table = rtl28xxu_table, 953 + }; 954 + 955 + /* module stuff */ 956 + static int __init rtl28xxu_module_init(void) 957 + { 958 + int ret; 959 + 960 + deb_info("%s:\n", __func__); 961 + 962 + ret = usb_register(&rtl28xxu_driver); 963 + if (ret) 964 + err("usb_register failed=%d", ret); 965 + 966 + return ret; 967 + } 968 + 969 + static void __exit rtl28xxu_module_exit(void) 970 + { 971 + deb_info("%s:\n", __func__); 972 + 973 + /* deregister this driver from the USB subsystem */ 974 + usb_deregister(&rtl28xxu_driver); 975 + } 976 + 977 + module_init(rtl28xxu_module_init); 978 + module_exit(rtl28xxu_module_exit); 979 + 980 + MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver"); 981 + MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 982 + MODULE_LICENSE("GPL");
+264
drivers/media/dvb/dvb-usb/rtl28xxu.h
··· 1 + /* 2 + * Realtek RTL28xxU DVB USB driver 3 + * 4 + * Copyright (C) 2009 Antti Palosaari <crope@iki.fi> 5 + * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License along 18 + * with this program; if not, write to the Free Software Foundation, Inc., 19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 + */ 21 + 22 + #ifndef RTL28XXU_H 23 + #define RTL28XXU_H 24 + 25 + #define DVB_USB_LOG_PREFIX "rtl28xxu" 26 + #include "dvb-usb.h" 27 + 28 + #define deb_info(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x01, args) 29 + #define deb_rc(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x02, args) 30 + #define deb_xfer(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x04, args) 31 + #define deb_reg(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x08, args) 32 + #define deb_i2c(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x10, args) 33 + #define deb_fw(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x20, args) 34 + 35 + #define deb_dump(r, t, v, i, b, l, func) { \ 36 + int loop_; \ 37 + func("%02x %02x %02x %02x %02x %02x %02x %02x", \ 38 + t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \ 39 + if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \ 40 + func(" >>> "); \ 41 + else \ 42 + func(" <<< "); \ 43 + for (loop_ = 0; loop_ < l; loop_++) \ 44 + func("%02x ", b[loop_]); \ 45 + func("\n");\ 46 + } 47 + 48 + /* 49 + * USB commands 50 + * (usb_control_msg() index parameter) 51 + */ 52 + 53 + #define DEMOD 0x0000 54 + #define USB 0x0100 55 + #define SYS 0x0200 56 + #define I2C 0x0300 57 + #define I2C_DA 0x0600 58 + 59 + #define CMD_WR_FLAG 0x0010 60 + #define CMD_DEMOD_RD 0x0000 61 + #define CMD_DEMOD_WR 0x0010 62 + #define CMD_USB_RD 0x0100 63 + #define CMD_USB_WR 0x0110 64 + #define CMD_SYS_RD 0x0200 65 + #define CMD_IR_RD 0x0201 66 + #define CMD_IR_WR 0x0211 67 + #define CMD_SYS_WR 0x0210 68 + #define CMD_I2C_RD 0x0300 69 + #define CMD_I2C_WR 0x0310 70 + #define CMD_I2C_DA_RD 0x0600 71 + #define CMD_I2C_DA_WR 0x0610 72 + 73 + 74 + struct rtl28xxu_priv { 75 + u8 chip_id; 76 + u8 tuner; 77 + u8 page; /* integrated demod active register page */ 78 + bool rc_active; 79 + }; 80 + 81 + enum rtl28xxu_chip_id { 82 + CHIP_ID_NONE, 83 + CHIP_ID_RTL2831U, 84 + CHIP_ID_RTL2832U, 85 + }; 86 + 87 + enum rtl28xxu_tuner { 88 + TUNER_NONE, 89 + 90 + TUNER_RTL2830_QT1010, 91 + TUNER_RTL2830_MT2060, 92 + TUNER_RTL2830_MXL5005S, 93 + 94 + TUNER_RTL2832_MT2266, 95 + TUNER_RTL2832_FC2580, 96 + TUNER_RTL2832_MT2063, 97 + TUNER_RTL2832_MAX3543, 98 + TUNER_RTL2832_TUA9001, 99 + TUNER_RTL2832_MXL5007T, 100 + TUNER_RTL2832_FC0012, 101 + TUNER_RTL2832_E4000, 102 + TUNER_RTL2832_TDA18272, 103 + TUNER_RTL2832_FC0013, 104 + }; 105 + 106 + struct rtl28xxu_req { 107 + u16 value; 108 + u16 index; 109 + u16 size; 110 + u8 *data; 111 + }; 112 + 113 + struct rtl28xxu_reg_val { 114 + u16 reg; 115 + u8 val; 116 + }; 117 + 118 + /* 119 + * memory map 120 + * 121 + * 0x0000 DEMOD : demodulator 122 + * 0x2000 USB : SIE, USB endpoint, debug, DMA 123 + * 0x3000 SYS : system 124 + * 0xfc00 RC : remote controller (not RTL2831U) 125 + */ 126 + 127 + /* 128 + * USB registers 129 + */ 130 + /* SIE Control Registers */ 131 + #define USB_SYSCTL 0x2000 /* USB system control */ 132 + #define USB_SYSCTL_0 0x2000 /* USB system control */ 133 + #define USB_SYSCTL_1 0x2001 /* USB system control */ 134 + #define USB_SYSCTL_2 0x2002 /* USB system control */ 135 + #define USB_SYSCTL_3 0x2003 /* USB system control */ 136 + #define USB_IRQSTAT 0x2008 /* SIE interrupt status */ 137 + #define USB_IRQEN 0x200C /* SIE interrupt enable */ 138 + #define USB_CTRL 0x2010 /* USB control */ 139 + #define USB_STAT 0x2014 /* USB status */ 140 + #define USB_DEVADDR 0x2018 /* USB device address */ 141 + #define USB_TEST 0x201C /* USB test mode */ 142 + #define USB_FRAME_NUMBER 0x2020 /* frame number */ 143 + #define USB_FIFO_ADDR 0x2028 /* address of SIE FIFO RAM */ 144 + #define USB_FIFO_CMD 0x202A /* SIE FIFO RAM access command */ 145 + #define USB_FIFO_DATA 0x2030 /* SIE FIFO RAM data */ 146 + /* Endpoint Registers */ 147 + #define EP0_SETUPA 0x20F8 /* EP 0 setup packet lower byte */ 148 + #define EP0_SETUPB 0x20FC /* EP 0 setup packet higher byte */ 149 + #define USB_EP0_CFG 0x2104 /* EP 0 configure */ 150 + #define USB_EP0_CTL 0x2108 /* EP 0 control */ 151 + #define USB_EP0_STAT 0x210C /* EP 0 status */ 152 + #define USB_EP0_IRQSTAT 0x2110 /* EP 0 interrupt status */ 153 + #define USB_EP0_IRQEN 0x2114 /* EP 0 interrupt enable */ 154 + #define USB_EP0_MAXPKT 0x2118 /* EP 0 max packet size */ 155 + #define USB_EP0_BC 0x2120 /* EP 0 FIFO byte counter */ 156 + #define USB_EPA_CFG 0x2144 /* EP A configure */ 157 + #define USB_EPA_CFG_0 0x2144 /* EP A configure */ 158 + #define USB_EPA_CFG_1 0x2145 /* EP A configure */ 159 + #define USB_EPA_CFG_2 0x2146 /* EP A configure */ 160 + #define USB_EPA_CFG_3 0x2147 /* EP A configure */ 161 + #define USB_EPA_CTL 0x2148 /* EP A control */ 162 + #define USB_EPA_CTL_0 0x2148 /* EP A control */ 163 + #define USB_EPA_CTL_1 0x2149 /* EP A control */ 164 + #define USB_EPA_CTL_2 0x214A /* EP A control */ 165 + #define USB_EPA_CTL_3 0x214B /* EP A control */ 166 + #define USB_EPA_STAT 0x214C /* EP A status */ 167 + #define USB_EPA_IRQSTAT 0x2150 /* EP A interrupt status */ 168 + #define USB_EPA_IRQEN 0x2154 /* EP A interrupt enable */ 169 + #define USB_EPA_MAXPKT 0x2158 /* EP A max packet size */ 170 + #define USB_EPA_MAXPKT_0 0x2158 /* EP A max packet size */ 171 + #define USB_EPA_MAXPKT_1 0x2159 /* EP A max packet size */ 172 + #define USB_EPA_MAXPKT_2 0x215A /* EP A max packet size */ 173 + #define USB_EPA_MAXPKT_3 0x215B /* EP A max packet size */ 174 + #define USB_EPA_FIFO_CFG 0x2160 /* EP A FIFO configure */ 175 + #define USB_EPA_FIFO_CFG_0 0x2160 /* EP A FIFO configure */ 176 + #define USB_EPA_FIFO_CFG_1 0x2161 /* EP A FIFO configure */ 177 + #define USB_EPA_FIFO_CFG_2 0x2162 /* EP A FIFO configure */ 178 + #define USB_EPA_FIFO_CFG_3 0x2163 /* EP A FIFO configure */ 179 + /* Debug Registers */ 180 + #define USB_PHYTSTDIS 0x2F04 /* PHY test disable */ 181 + #define USB_TOUT_VAL 0x2F08 /* USB time-out time */ 182 + #define USB_VDRCTRL 0x2F10 /* UTMI vendor signal control */ 183 + #define USB_VSTAIN 0x2F14 /* UTMI vendor signal status in */ 184 + #define USB_VLOADM 0x2F18 /* UTMI load vendor signal status in */ 185 + #define USB_VSTAOUT 0x2F1C /* UTMI vendor signal status out */ 186 + #define USB_UTMI_TST 0x2F80 /* UTMI test */ 187 + #define USB_UTMI_STATUS 0x2F84 /* UTMI status */ 188 + #define USB_TSTCTL 0x2F88 /* test control */ 189 + #define USB_TSTCTL2 0x2F8C /* test control 2 */ 190 + #define USB_PID_FORCE 0x2F90 /* force PID */ 191 + #define USB_PKTERR_CNT 0x2F94 /* packet error counter */ 192 + #define USB_RXERR_CNT 0x2F98 /* RX error counter */ 193 + #define USB_MEM_BIST 0x2F9C /* MEM BIST test */ 194 + #define USB_SLBBIST 0x2FA0 /* self-loop-back BIST */ 195 + #define USB_CNTTEST 0x2FA4 /* counter test */ 196 + #define USB_PHYTST 0x2FC0 /* USB PHY test */ 197 + #define USB_DBGIDX 0x2FF0 /* select individual block debug signal */ 198 + #define USB_DBGMUX 0x2FF4 /* debug signal module mux */ 199 + 200 + /* 201 + * SYS registers 202 + */ 203 + /* demod control registers */ 204 + #define SYS_SYS0 0x3000 /* include DEMOD_CTL, GPO, GPI, GPOE */ 205 + #define SYS_DEMOD_CTL 0x3000 /* control register for DVB-T demodulator */ 206 + /* GPIO registers */ 207 + #define SYS_GPIO_OUT_VAL 0x3001 /* output value of GPIO */ 208 + #define SYS_GPIO_IN_VAL 0x3002 /* input value of GPIO */ 209 + #define SYS_GPIO_OUT_EN 0x3003 /* output enable of GPIO */ 210 + #define SYS_SYS1 0x3004 /* include GPD, SYSINTE, SYSINTS, GP_CFG0 */ 211 + #define SYS_GPIO_DIR 0x3004 /* direction control for GPIO */ 212 + #define SYS_SYSINTE 0x3005 /* system interrupt enable */ 213 + #define SYS_SYSINTS 0x3006 /* system interrupt status */ 214 + #define SYS_GPIO_CFG0 0x3007 /* PAD configuration for GPIO0-GPIO3 */ 215 + #define SYS_SYS2 0x3008 /* include GP_CFG1 and 3 reserved bytes */ 216 + #define SYS_GPIO_CFG1 0x3008 /* PAD configuration for GPIO4 */ 217 + #define SYS_DEMOD_CTL1 0x300B 218 + 219 + /* IrDA registers */ 220 + #define SYS_IRRC_PSR 0x3020 /* IR protocol selection */ 221 + #define SYS_IRRC_PER 0x3024 /* IR protocol extension */ 222 + #define SYS_IRRC_SF 0x3028 /* IR sampling frequency */ 223 + #define SYS_IRRC_DPIR 0x302C /* IR data package interval */ 224 + #define SYS_IRRC_CR 0x3030 /* IR control */ 225 + #define SYS_IRRC_RP 0x3034 /* IR read port */ 226 + #define SYS_IRRC_SR 0x3038 /* IR status */ 227 + /* I2C master registers */ 228 + #define SYS_I2CCR 0x3040 /* I2C clock */ 229 + #define SYS_I2CMCR 0x3044 /* I2C master control */ 230 + #define SYS_I2CMSTR 0x3048 /* I2C master SCL timing */ 231 + #define SYS_I2CMSR 0x304C /* I2C master status */ 232 + #define SYS_I2CMFR 0x3050 /* I2C master FIFO */ 233 + 234 + /* 235 + * IR registers 236 + */ 237 + #define IR_RX_BUF 0xFC00 238 + #define IR_RX_IE 0xFD00 239 + #define IR_RX_IF 0xFD01 240 + #define IR_RX_CTRL 0xFD02 241 + #define IR_RX_CFG 0xFD03 242 + #define IR_MAX_DURATION0 0xFD04 243 + #define IR_MAX_DURATION1 0xFD05 244 + #define IR_IDLE_LEN0 0xFD06 245 + #define IR_IDLE_LEN1 0xFD07 246 + #define IR_GLITCH_LEN 0xFD08 247 + #define IR_RX_BUF_CTRL 0xFD09 248 + #define IR_RX_BUF_DATA 0xFD0A 249 + #define IR_RX_BC 0xFD0B 250 + #define IR_RX_CLK 0xFD0C 251 + #define IR_RX_C_COUNT_L 0xFD0D 252 + #define IR_RX_C_COUNT_H 0xFD0E 253 + #define IR_SUSPEND_CTRL 0xFD10 254 + #define IR_ERR_TOL_CTRL 0xFD11 255 + #define IR_UNIT_LEN 0xFD12 256 + #define IR_ERR_TOL_LEN 0xFD13 257 + #define IR_MAX_H_TOL_LEN 0xFD14 258 + #define IR_MAX_L_TOL_LEN 0xFD15 259 + #define IR_MASK_CTRL 0xFD16 260 + #define IR_MASK_DATA 0xFD17 261 + #define IR_RES_MASK_ADDR 0xFD18 262 + #define IR_RES_MASK_T_LEN 0xFD19 263 + 264 + #endif
+15
drivers/media/dvb/frontends/Kconfig
··· 425 425 help 426 426 Say Y when you want to support this frontend. 427 427 428 + config DVB_RTL2830 429 + tristate "Realtek RTL2830 DVB-T" 430 + depends on DVB_CORE && I2C 431 + default m if DVB_FE_CUSTOMISE 432 + help 433 + Say Y when you want to support this frontend. 434 + 428 435 comment "DVB-C (cable) frontends" 429 436 depends on DVB_CORE 430 437 ··· 703 696 default m if DVB_FE_CUSTOMISE 704 697 help 705 698 A DVB-T tuner module. 699 + Say Y when you want to support this frontend. 700 + 701 + config DVB_M88RS2000 702 + tristate "M88RS2000 DVB-S demodulator and tuner" 703 + depends on DVB_CORE && I2C 704 + default m if DVB_FE_CUSTOMISE 705 + help 706 + A DVB-S tuner module. 706 707 Say Y when you want to support this frontend. 707 708 708 709 comment "Tools to develop new frontends"
+4 -2
drivers/media/dvb/frontends/Makefile
··· 2 2 # Makefile for the kernel DVB frontend device drivers. 3 3 # 4 4 5 - ccflags-y += -Idrivers/media/dvb/dvb-core/ 6 - ccflags-y += -Idrivers/media/common/tuners/ 5 + ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core/ 6 + ccflags-y += -I$(srctree)/drivers/media/common/tuners/ 7 7 8 8 stb0899-objs = stb0899_drv.o stb0899_algo.o 9 9 stv0900-objs = stv0900_core.o stv0900_sw.o ··· 96 96 obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o 97 97 obj-$(CONFIG_DVB_A8293) += a8293.o 98 98 obj-$(CONFIG_DVB_TDA10071) += tda10071.o 99 + obj-$(CONFIG_DVB_RTL2830) += rtl2830.o 100 + obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o 99 101
+1 -12
drivers/media/dvb/frontends/au8522_decoder.c
··· 839 839 .id_table = au8522_id, 840 840 }; 841 841 842 - static __init int init_au8522(void) 843 - { 844 - return i2c_add_driver(&au8522_driver); 845 - } 846 - 847 - static __exit void exit_au8522(void) 848 - { 849 - i2c_del_driver(&au8522_driver); 850 - } 851 - 852 - module_init(init_au8522); 853 - module_exit(exit_au8522); 842 + module_i2c_driver(au8522_driver);
+5 -5
drivers/media/dvb/frontends/au8522_dig.c
··· 588 588 (state->current_modulation == c->modulation)) 589 589 return 0; 590 590 591 - au8522_enable_modulation(fe, c->modulation); 592 - 593 - /* Allow the demod to settle */ 594 - msleep(100); 595 - 596 591 if (fe->ops.tuner_ops.set_params) { 597 592 if (fe->ops.i2c_gate_ctrl) 598 593 fe->ops.i2c_gate_ctrl(fe, 1); ··· 598 603 599 604 if (ret < 0) 600 605 return ret; 606 + 607 + /* Allow the tuner to settle */ 608 + msleep(100); 609 + 610 + au8522_enable_modulation(fe, c->modulation); 601 611 602 612 state->current_frequency = c->frequency; 603 613
+19 -3
drivers/media/dvb/frontends/cx22702.c
··· 502 502 u16 *signal_strength) 503 503 { 504 504 struct cx22702_state *state = fe->demodulator_priv; 505 + u8 reg23; 505 506 506 - u16 rs_ber; 507 - rs_ber = cx22702_readreg(state, 0x23); 508 - *signal_strength = (rs_ber << 8) | rs_ber; 507 + /* 508 + * Experience suggests that the strength signal register works as 509 + * follows: 510 + * - In the absence of signal, value is 0xff. 511 + * - In the presence of a weak signal, bit 7 is set, not sure what 512 + * the lower 7 bits mean. 513 + * - In the presence of a strong signal, the register holds a 7-bit 514 + * value (bit 7 is cleared), with greater values standing for 515 + * weaker signals. 516 + */ 517 + reg23 = cx22702_readreg(state, 0x23); 518 + if (reg23 & 0x80) { 519 + *signal_strength = 0; 520 + } else { 521 + reg23 = ~reg23 & 0x7f; 522 + /* Scale to 16 bit */ 523 + *signal_strength = (reg23 << 9) | (reg23 << 2) | (reg23 >> 5); 524 + } 509 525 510 526 return 0; 511 527 }
+1 -1
drivers/media/dvb/frontends/dib0090.c
··· 519 519 return 0; 520 520 521 521 identification_error: 522 - return -EIO;; 522 + return -EIO; 523 523 } 524 524 525 525 static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
+96 -25
drivers/media/dvb/frontends/dib9000.c
··· 33 33 34 34 /* lock */ 35 35 #define DIB_LOCK struct mutex 36 - #define DibAcquireLock(lock) do { if (mutex_lock_interruptible(lock) < 0) dprintk("could not get the lock"); } while (0) 36 + #define DibAcquireLock(lock) mutex_lock_interruptible(lock) 37 37 #define DibReleaseLock(lock) mutex_unlock(lock) 38 38 #define DibInitLock(lock) mutex_init(lock) 39 39 #define DibFreeLock(lock) ··· 446 446 if (!state->platform.risc.fw_is_running) 447 447 return -EIO; 448 448 449 - DibAcquireLock(&state->platform.risc.mem_lock); 449 + if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) { 450 + dprintk("could not get the lock"); 451 + return -EINTR; 452 + } 450 453 dib9000_risc_mem_setup(state, cmd | 0x80); 451 454 dib9000_risc_mem_read_chunks(state, b, len); 452 455 DibReleaseLock(&state->platform.risc.mem_lock); ··· 462 459 if (!state->platform.risc.fw_is_running) 463 460 return -EIO; 464 461 465 - DibAcquireLock(&state->platform.risc.mem_lock); 462 + if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) { 463 + dprintk("could not get the lock"); 464 + return -EINTR; 465 + } 466 466 dib9000_risc_mem_setup(state, cmd); 467 467 dib9000_risc_mem_write_chunks(state, b, m->size); 468 468 DibReleaseLock(&state->platform.risc.mem_lock); ··· 537 531 if (!state->platform.risc.fw_is_running) 538 532 return -EINVAL; 539 533 540 - DibAcquireLock(&state->platform.risc.mbx_if_lock); 534 + if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) { 535 + dprintk("could not get the lock"); 536 + return -EINTR; 537 + } 541 538 tmp = MAX_MAILBOX_TRY; 542 539 do { 543 540 size = dib9000_read_word_attr(state, 1043, attr) & 0xff; ··· 602 593 if (!state->platform.risc.fw_is_running) 603 594 return 0; 604 595 605 - DibAcquireLock(&state->platform.risc.mbx_if_lock); 596 + if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) { 597 + dprintk("could not get the lock"); 598 + return 0; 599 + } 606 600 if (risc_id == 1) 607 601 mc_base = 16; 608 602 else ··· 713 701 if (!state->platform.risc.fw_is_running) 714 702 return -1; 715 703 716 - DibAcquireLock(&state->platform.risc.mbx_lock); 704 + if (DibAcquireLock(&state->platform.risc.mbx_lock) < 0) { 705 + dprintk("could not get the lock"); 706 + return -1; 707 + } 717 708 718 709 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */ 719 710 ret = dib9000_mbx_fetch_to_cache(state, attr); ··· 1193 1178 struct dibDVBTChannel *ch; 1194 1179 int ret = 0; 1195 1180 1196 - DibAcquireLock(&state->platform.risc.mem_mbx_lock); 1181 + if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 1182 + dprintk("could not get the lock"); 1183 + return -EINTR; 1184 + } 1197 1185 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 1198 1186 ret = -EIO; 1199 1187 goto error; ··· 1678 1660 p[12] = 0; 1679 1661 } 1680 1662 1681 - DibAcquireLock(&state->platform.risc.mem_mbx_lock); 1663 + if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 1664 + dprintk("could not get the lock"); 1665 + return 0; 1666 + } 1682 1667 1683 1668 dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p); 1684 1669 ··· 1789 1768 return 0; 1790 1769 } 1791 1770 1792 - DibAcquireLock(&state->demod_lock); 1771 + if (DibAcquireLock(&state->demod_lock) < 0) { 1772 + dprintk("could not get the lock"); 1773 + return -EINTR; 1774 + } 1793 1775 1794 1776 val = dib9000_read_word(state, 294 + 1) & 0xffef; 1795 1777 val |= (onoff & 0x1) << 4; ··· 1824 1800 return 0; 1825 1801 } 1826 1802 1827 - DibAcquireLock(&state->demod_lock); 1803 + if (DibAcquireLock(&state->demod_lock) < 0) { 1804 + dprintk("could not get the lock"); 1805 + return -EINTR; 1806 + } 1828 1807 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); 1829 1808 ret = dib9000_write_word(state, 300 + 1 + id, 1830 1809 onoff ? (1 << 13) | pid : 0); ··· 1875 1848 u8 index_frontend; 1876 1849 int ret = 0; 1877 1850 1878 - DibAcquireLock(&state->demod_lock); 1851 + if (DibAcquireLock(&state->demod_lock) < 0) { 1852 + dprintk("could not get the lock"); 1853 + return -EINTR; 1854 + } 1879 1855 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 1880 1856 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]); 1881 1857 if (ret < 0) ··· 1904 1874 fe_status_t stat; 1905 1875 int ret = 0; 1906 1876 1907 - if (state->get_frontend_internal == 0) 1908 - DibAcquireLock(&state->demod_lock); 1877 + if (state->get_frontend_internal == 0) { 1878 + if (DibAcquireLock(&state->demod_lock) < 0) { 1879 + dprintk("could not get the lock"); 1880 + return -EINTR; 1881 + } 1882 + } 1909 1883 1910 1884 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 1911 1885 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); ··· 2012 1978 } 2013 1979 2014 1980 state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */ 2015 - DibAcquireLock(&state->demod_lock); 1981 + if (DibAcquireLock(&state->demod_lock) < 0) { 1982 + dprintk("could not get the lock"); 1983 + return 0; 1984 + } 2016 1985 2017 1986 fe->dtv_property_cache.delivery_system = SYS_DVBT; 2018 1987 ··· 2175 2138 u8 index_frontend; 2176 2139 u16 lock = 0, lock_slave = 0; 2177 2140 2178 - DibAcquireLock(&state->demod_lock); 2141 + if (DibAcquireLock(&state->demod_lock) < 0) { 2142 + dprintk("could not get the lock"); 2143 + return -EINTR; 2144 + } 2179 2145 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 2180 2146 lock_slave |= dib9000_read_lock(state->fe[index_frontend]); 2181 2147 ··· 2208 2168 u16 *c; 2209 2169 int ret = 0; 2210 2170 2211 - DibAcquireLock(&state->demod_lock); 2212 - DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2171 + if (DibAcquireLock(&state->demod_lock) < 0) { 2172 + dprintk("could not get the lock"); 2173 + return -EINTR; 2174 + } 2175 + if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 2176 + dprintk("could not get the lock"); 2177 + ret = -EINTR; 2178 + goto error; 2179 + } 2213 2180 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2214 2181 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2215 2182 ret = -EIO; ··· 2243 2196 u16 val; 2244 2197 int ret = 0; 2245 2198 2246 - DibAcquireLock(&state->demod_lock); 2199 + if (DibAcquireLock(&state->demod_lock) < 0) { 2200 + dprintk("could not get the lock"); 2201 + return -EINTR; 2202 + } 2247 2203 *strength = 0; 2248 2204 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 2249 2205 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val); ··· 2256 2206 *strength += val; 2257 2207 } 2258 2208 2259 - DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2209 + if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 2210 + dprintk("could not get the lock"); 2211 + ret = -EINTR; 2212 + goto error; 2213 + } 2260 2214 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2215 + DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2261 2216 ret = -EIO; 2262 2217 goto error; 2263 2218 } ··· 2287 2232 u32 n, s, exp; 2288 2233 u16 val; 2289 2234 2290 - DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2291 - if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) 2292 - return -EIO; 2235 + if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 2236 + dprintk("could not get the lock"); 2237 + return 0; 2238 + } 2239 + if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2240 + DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2241 + return 0; 2242 + } 2293 2243 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); 2294 2244 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2295 2245 ··· 2326 2266 u8 index_frontend; 2327 2267 u32 snr_master; 2328 2268 2329 - DibAcquireLock(&state->demod_lock); 2269 + if (DibAcquireLock(&state->demod_lock) < 0) { 2270 + dprintk("could not get the lock"); 2271 + return -EINTR; 2272 + } 2330 2273 snr_master = dib9000_get_snr(fe); 2331 2274 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 2332 2275 snr_master += dib9000_get_snr(state->fe[index_frontend]); ··· 2351 2288 u16 *c = (u16 *)state->i2c_read_buffer; 2352 2289 int ret = 0; 2353 2290 2354 - DibAcquireLock(&state->demod_lock); 2355 - DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2291 + if (DibAcquireLock(&state->demod_lock) < 0) { 2292 + dprintk("could not get the lock"); 2293 + return -EINTR; 2294 + } 2295 + if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) { 2296 + dprintk("could not get the lock"); 2297 + ret = -EINTR; 2298 + goto error; 2299 + } 2356 2300 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2301 + DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2357 2302 ret = -EIO; 2358 2303 goto error; 2359 2304 }
+3 -3
drivers/media/dvb/frontends/drxd_hard.c
··· 101 101 102 102 struct SNoiseCal { 103 103 int cpOpt; 104 - u16 cpNexpOfs; 105 - u16 tdCal2k; 106 - u16 tdCal8k; 104 + short cpNexpOfs; 105 + short tdCal2k; 106 + short tdCal8k; 107 107 }; 108 108 109 109 enum app_env {
+15 -8
drivers/media/dvb/frontends/drxk.h
··· 7 7 /** 8 8 * struct drxk_config - Configure the initial parameters for DRX-K 9 9 * 10 - * adr: I2C Address of the DRX-K 11 - * parallel_ts: true means that the device uses parallel TS, 10 + * @adr: I2C Address of the DRX-K 11 + * @parallel_ts: True means that the device uses parallel TS, 12 12 * Serial otherwise. 13 - * single_master: Device is on the single master mode 14 - * no_i2c_bridge: Don't switch the I2C bridge to talk with tuner 15 - * antenna_gpio: GPIO bit used to control the antenna 16 - * antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 13 + * @dynamic_clk: True means that the clock will be dynamically 14 + * adjusted. Static clock otherwise. 15 + * @enable_merr_cfg: Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG. 16 + * @single_master: Device is on the single master mode 17 + * @no_i2c_bridge: Don't switch the I2C bridge to talk with tuner 18 + * @antenna_gpio: GPIO bit used to control the antenna 19 + * @antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 17 20 * means that 1=DVBC, 0 = DVBT. Zero means the opposite. 18 - * microcode_name: Name of the firmware file with the microcode 21 + * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength. 22 + * @microcode_name: Name of the firmware file with the microcode 19 23 * 20 24 * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is 21 25 * UIO-3. ··· 29 25 bool single_master; 30 26 bool no_i2c_bridge; 31 27 bool parallel_ts; 28 + bool dynamic_clk; 29 + bool enable_merr_cfg; 32 30 33 31 bool antenna_dvbt; 34 32 u16 antenna_gpio; 35 33 36 - int chunk_size; 34 + u8 mpeg_out_clk_strength; 35 + int chunk_size; 37 36 38 37 const char *microcode_name; 39 38 };
+26 -20
drivers/media/dvb/frontends/drxk_hard.c
··· 90 90 #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03) 91 91 #endif 92 92 93 - #ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH 94 - #define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06) 95 - #endif 96 - 97 93 #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700 98 94 #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500 99 95 ··· 645 649 u32 ulQual83 = DEFAULT_MER_83; 646 650 u32 ulQual93 = DEFAULT_MER_93; 647 651 648 - u32 ulDVBTStaticTSClock = 1; 649 - u32 ulDVBCStaticTSClock = 1; 650 - 651 652 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; 652 653 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; 653 654 ··· 654 661 u32 ulGPIOCfg = 0x0113; 655 662 u32 ulInvertTSClock = 0; 656 663 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; 657 - u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH; 658 664 u32 ulDVBTBitrate = 50000000; 659 665 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; 660 666 ··· 806 814 state->m_invertSTR = false; /* If TRUE; invert STR signals */ 807 815 state->m_invertVAL = false; /* If TRUE; invert VAL signals */ 808 816 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */ 809 - state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0); 810 - state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0); 817 + 811 818 /* If TRUE; static MPEG clockrate will be used; 812 819 otherwise clockrate will adapt to the bitrate of the TS */ 813 820 ··· 814 823 state->m_DVBCBitrate = ulDVBCBitrate; 815 824 816 825 state->m_TSDataStrength = (ulTSDataStrength & 0x07); 817 - state->m_TSClockkStrength = (ulTSClockkStrength & 0x07); 818 826 819 827 /* Maximum bitrate in b/s in case static clockrate is selected */ 820 828 state->m_mpegTsStaticBitrate = 19392658; ··· 1178 1188 int status = -1; 1179 1189 u16 sioPdrMclkCfg = 0; 1180 1190 u16 sioPdrMdxCfg = 0; 1191 + u16 err_cfg = 0; 1181 1192 1182 1193 dprintk(1, ": mpeg %s, %s mode\n", 1183 1194 mpegEnable ? "enable" : "disable", ··· 1244 1253 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg); 1245 1254 if (status < 0) 1246 1255 goto error; 1247 - status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */ 1256 + 1257 + if (state->enable_merr_cfg) 1258 + err_cfg = sioPdrMdxCfg; 1259 + 1260 + status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg); 1248 1261 if (status < 0) 1249 1262 goto error; 1250 - status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */ 1263 + status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg); 1251 1264 if (status < 0) 1252 1265 goto error; 1266 + 1253 1267 if (state->m_enableParallel == true) { 1254 1268 /* paralel -> enable MD1 to MD7 */ 1255 1269 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg); ··· 6065 6069 if (status < 0) 6066 6070 goto error; 6067 6071 6068 - if (!state->microcode_name) 6069 - load_microcode(state, "drxk_a3.mc"); 6070 - else 6072 + if (state->microcode_name) 6071 6073 load_microcode(state, state->microcode_name); 6072 6074 6073 6075 /* disable token-ring bus through OFDM block for possible ucode upload */ ··· 6316 6322 switch (p->delivery_system) { 6317 6323 case SYS_DVBC_ANNEX_A: 6318 6324 case SYS_DVBC_ANNEX_C: 6325 + case SYS_DVBT: 6319 6326 sets->min_delay_ms = 3000; 6320 6327 sets->max_drift = 0; 6321 6328 sets->step_size = 0; 6322 6329 return 0; 6323 6330 default: 6324 - /* 6325 - * For DVB-T, let it use the default DVB core way, that is: 6326 - * fepriv->step_size = fe->ops.info.frequency_stepsize * 2 6327 - */ 6328 6331 return -EINVAL; 6329 6332 } 6330 6333 } ··· 6381 6390 state->antenna_gpio = config->antenna_gpio; 6382 6391 state->antenna_dvbt = config->antenna_dvbt; 6383 6392 state->m_ChunkSize = config->chunk_size; 6393 + state->enable_merr_cfg = config->enable_merr_cfg; 6394 + 6395 + if (config->dynamic_clk) { 6396 + state->m_DVBTStaticCLK = 0; 6397 + state->m_DVBCStaticCLK = 0; 6398 + } else { 6399 + state->m_DVBTStaticCLK = 1; 6400 + state->m_DVBCStaticCLK = 1; 6401 + } 6402 + 6403 + 6404 + if (config->mpeg_out_clk_strength) 6405 + state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07; 6406 + else 6407 + state->m_TSClockkStrength = 0x06; 6384 6408 6385 6409 if (config->parallel_ts) 6386 6410 state->m_enableParallel = true;
+1
drivers/media/dvb/frontends/drxk_hard.h
··· 332 332 333 333 u16 UIO_mask; /* Bits used by UIO */ 334 334 335 + bool enable_merr_cfg; 335 336 bool single_master; 336 337 bool no_i2c_bridge; 337 338 bool antenna_dvbt;
+5
drivers/media/dvb/frontends/it913x-fe-priv.h
··· 201 201 QAM_64, 202 202 }; 203 203 204 + enum { 205 + PRIORITY_HIGH = 0, /* High-priority stream */ 206 + PRIORITY_LOW, /* Low-priority stream */ 207 + }; 208 + 204 209 /* Standard demodulator functions */ 205 210 static struct it913xset set_solo_fe[] = { 206 211 {PRO_LINK, GPIOH5_EN, {0x01}, 0x01},
+81 -10
drivers/media/dvb/frontends/it913x-fe.c
··· 57 57 u32 frequency; 58 58 fe_modulation_t constellation; 59 59 fe_transmit_mode_t transmission_mode; 60 + u8 priority; 60 61 u32 crystalFrequency; 61 62 u32 adcFrequency; 62 63 u8 tuner_type; ··· 501 500 return 0; 502 501 } 503 502 503 + /* FEC values based on fe_code_rate_t non supported values 0*/ 504 + int it913x_qpsk_pval[] = {0, -93, -91, -90, 0, -89, -88}; 505 + int it913x_16qam_pval[] = {0, -87, -85, -84, 0, -83, -82}; 506 + int it913x_64qam_pval[] = {0, -82, -80, -78, 0, -77, -76}; 507 + 508 + static int it913x_get_signal_strength(struct dvb_frontend *fe) 509 + { 510 + struct dtv_frontend_properties *p = &fe->dtv_property_cache; 511 + struct it913x_fe_state *state = fe->demodulator_priv; 512 + u8 code_rate; 513 + int ret, temp; 514 + u8 lna_gain_os; 515 + 516 + ret = it913x_read_reg_u8(state, VAR_P_INBAND); 517 + if (ret < 0) 518 + return ret; 519 + 520 + /* VHF/UHF gain offset */ 521 + if (state->frequency < 300000000) 522 + lna_gain_os = 7; 523 + else 524 + lna_gain_os = 14; 525 + 526 + temp = (ret - 100) - lna_gain_os; 527 + 528 + if (state->priority == PRIORITY_HIGH) 529 + code_rate = p->code_rate_HP; 530 + else 531 + code_rate = p->code_rate_LP; 532 + 533 + if (code_rate >= ARRAY_SIZE(it913x_qpsk_pval)) 534 + return -EINVAL; 535 + 536 + deb_info("Reg VAR_P_INBAND:%d Calc Offset Value:%d", ret, temp); 537 + 538 + /* Apply FEC offset values*/ 539 + switch (p->modulation) { 540 + case QPSK: 541 + temp -= it913x_qpsk_pval[code_rate]; 542 + break; 543 + case QAM_16: 544 + temp -= it913x_16qam_pval[code_rate]; 545 + break; 546 + case QAM_64: 547 + temp -= it913x_64qam_pval[code_rate]; 548 + break; 549 + default: 550 + return -EINVAL; 551 + } 552 + 553 + if (temp < -15) 554 + ret = 0; 555 + else if ((-15 <= temp) && (temp < 0)) 556 + ret = (2 * (temp + 15)) / 3; 557 + else if ((0 <= temp) && (temp < 20)) 558 + ret = 4 * temp + 10; 559 + else if ((20 <= temp) && (temp < 35)) 560 + ret = (2 * (temp - 20)) / 3 + 90; 561 + else if (temp >= 35) 562 + ret = 100; 563 + 564 + deb_info("Signal Strength :%d", ret); 565 + 566 + return ret; 567 + } 568 + 504 569 static int it913x_fe_read_signal_strength(struct dvb_frontend *fe, 505 570 u16 *strength) 506 571 { 507 572 struct it913x_fe_state *state = fe->demodulator_priv; 508 - int ret = it913x_read_reg_u8(state, SIGNAL_LEVEL); 509 - /*SIGNAL_LEVEL always returns 100%! so using FE_HAS_SIGNAL as switch*/ 510 - if (state->it913x_status & FE_HAS_SIGNAL) 511 - ret = (ret * 0xff) / 0x64; 512 - else 513 - ret = 0x0; 514 - ret |= ret << 0x8; 515 - *strength = ret; 516 - return 0; 573 + int ret = 0; 574 + if (state->config->read_slevel) { 575 + if (state->it913x_status & FE_HAS_SIGNAL) 576 + ret = it913x_read_reg_u8(state, SIGNAL_LEVEL); 577 + } else 578 + ret = it913x_get_signal_strength(fe); 579 + 580 + if (ret >= 0) 581 + *strength = (u16)((u32)ret * 0xffff / 0x64); 582 + 583 + return (ret < 0) ? -ENODEV : 0; 517 584 } 518 585 519 586 static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr) ··· 674 605 675 606 if (reg[2] < 4) 676 607 p->hierarchy = fe_hi[reg[2]]; 608 + 609 + state->priority = reg[5]; 677 610 678 611 p->code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE; 679 612 p->code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE; ··· 1043 972 1044 973 MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); 1045 974 MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); 1046 - MODULE_VERSION("1.13"); 975 + MODULE_VERSION("1.15"); 1047 976 MODULE_LICENSE("GPL");
+4
drivers/media/dvb/frontends/it913x-fe.h
··· 34 34 u8 tuner_id_1; 35 35 u8 dual_mode; 36 36 u8 adf; 37 + /* option to read SIGNAL_LEVEL */ 38 + u8 read_slevel; 37 39 }; 38 40 39 41 #if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \ ··· 170 168 #define EST_SIGNAL_LEVEL 0x004a 171 169 #define FREE_BAND 0x004b 172 170 #define SUSPEND_FLAG 0x004c 171 + #define VAR_P_INBAND 0x00f7 172 + 173 173 /* Build in tuner types */ 174 174 #define IT9137 0x38 175 175 #define IT9135_38 0x38
+4 -2
drivers/media/dvb/frontends/lgdt330x.c
··· 104 104 * then reads the data returned for (len) bytes. 105 105 */ 106 106 107 - static u8 i2c_read_demod_bytes (struct lgdt330x_state* state, 108 - enum I2C_REG reg, u8* buf, int len) 107 + static int i2c_read_demod_bytes(struct lgdt330x_state *state, 108 + enum I2C_REG reg, u8 *buf, int len) 109 109 { 110 110 u8 wr [] = { reg }; 111 111 struct i2c_msg msg [] = { ··· 118 118 ret = i2c_transfer(state->i2c, msg, 2); 119 119 if (ret != 2) { 120 120 printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret); 121 + if (ret >= 0) 122 + ret = -EIO; 121 123 } else { 122 124 ret = 0; 123 125 }
+904
drivers/media/dvb/frontends/m88rs2000.c
··· 1 + /* 2 + Driver for M88RS2000 demodulator and tuner 3 + 4 + Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.com) 5 + Beta Driver 6 + 7 + Include various calculation code from DS3000 driver. 8 + Copyright (C) 2009 Konstantin Dimitrov. 9 + 10 + This program is free software; you can redistribute it and/or modify 11 + it under the terms of the GNU General Public License as published by 12 + the Free Software Foundation; either version 2 of the License, or 13 + (at your option) any later version. 14 + 15 + This program is distributed in the hope that it will be useful, 16 + but WITHOUT ANY WARRANTY; without even the implied warranty of 17 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 + GNU General Public License for more details. 19 + 20 + You should have received a copy of the GNU General Public License 21 + along with this program; if not, write to the Free Software 22 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 + 24 + */ 25 + #include <linux/init.h> 26 + #include <linux/module.h> 27 + #include <linux/device.h> 28 + #include <linux/jiffies.h> 29 + #include <linux/string.h> 30 + #include <linux/slab.h> 31 + #include <linux/types.h> 32 + 33 + 34 + #include "dvb_frontend.h" 35 + #include "m88rs2000.h" 36 + 37 + struct m88rs2000_state { 38 + struct i2c_adapter *i2c; 39 + const struct m88rs2000_config *config; 40 + struct dvb_frontend frontend; 41 + u8 no_lock_count; 42 + u32 tuner_frequency; 43 + u32 symbol_rate; 44 + fe_code_rate_t fec_inner; 45 + u8 tuner_level; 46 + int errmode; 47 + }; 48 + 49 + static int m88rs2000_debug; 50 + 51 + module_param_named(debug, m88rs2000_debug, int, 0644); 52 + MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."); 53 + 54 + #define dprintk(level, args...) do { \ 55 + if (level & m88rs2000_debug) \ 56 + printk(KERN_DEBUG "m88rs2000-fe: " args); \ 57 + } while (0) 58 + 59 + #define deb_info(args...) dprintk(0x01, args) 60 + #define info(format, arg...) \ 61 + printk(KERN_INFO "m88rs2000-fe: " format "\n" , ## arg) 62 + 63 + static int m88rs2000_writereg(struct m88rs2000_state *state, u8 tuner, 64 + u8 reg, u8 data) 65 + { 66 + int ret; 67 + u8 addr = (tuner == 0) ? state->config->tuner_addr : 68 + state->config->demod_addr; 69 + u8 buf[] = { reg, data }; 70 + struct i2c_msg msg = { 71 + .addr = addr, 72 + .flags = 0, 73 + .buf = buf, 74 + .len = 2 75 + }; 76 + 77 + ret = i2c_transfer(state->i2c, &msg, 1); 78 + 79 + if (ret != 1) 80 + deb_info("%s: writereg error (reg == 0x%02x, val == 0x%02x, " 81 + "ret == %i)\n", __func__, reg, data, ret); 82 + 83 + return (ret != 1) ? -EREMOTEIO : 0; 84 + } 85 + 86 + static int m88rs2000_demod_write(struct m88rs2000_state *state, u8 reg, u8 data) 87 + { 88 + return m88rs2000_writereg(state, 1, reg, data); 89 + } 90 + 91 + static int m88rs2000_tuner_write(struct m88rs2000_state *state, u8 reg, u8 data) 92 + { 93 + m88rs2000_demod_write(state, 0x81, 0x84); 94 + udelay(10); 95 + return m88rs2000_writereg(state, 0, reg, data); 96 + 97 + } 98 + 99 + static int m88rs2000_write(struct dvb_frontend *fe, const u8 buf[], int len) 100 + { 101 + struct m88rs2000_state *state = fe->demodulator_priv; 102 + 103 + if (len != 2) 104 + return -EINVAL; 105 + 106 + return m88rs2000_writereg(state, 1, buf[0], buf[1]); 107 + } 108 + 109 + static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 tuner, u8 reg) 110 + { 111 + int ret; 112 + u8 b0[] = { reg }; 113 + u8 b1[] = { 0 }; 114 + u8 addr = (tuner == 0) ? state->config->tuner_addr : 115 + state->config->demod_addr; 116 + struct i2c_msg msg[] = { 117 + { 118 + .addr = addr, 119 + .flags = 0, 120 + .buf = b0, 121 + .len = 1 122 + }, { 123 + .addr = addr, 124 + .flags = I2C_M_RD, 125 + .buf = b1, 126 + .len = 1 127 + } 128 + }; 129 + 130 + ret = i2c_transfer(state->i2c, msg, 2); 131 + 132 + if (ret != 2) 133 + deb_info("%s: readreg error (reg == 0x%02x, ret == %i)\n", 134 + __func__, reg, ret); 135 + 136 + return b1[0]; 137 + } 138 + 139 + static u8 m88rs2000_demod_read(struct m88rs2000_state *state, u8 reg) 140 + { 141 + return m88rs2000_readreg(state, 1, reg); 142 + } 143 + 144 + static u8 m88rs2000_tuner_read(struct m88rs2000_state *state, u8 reg) 145 + { 146 + m88rs2000_demod_write(state, 0x81, 0x85); 147 + udelay(10); 148 + return m88rs2000_readreg(state, 0, reg); 149 + } 150 + 151 + static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate) 152 + { 153 + struct m88rs2000_state *state = fe->demodulator_priv; 154 + int ret; 155 + u32 temp; 156 + u8 b[3]; 157 + 158 + if ((srate < 1000000) || (srate > 45000000)) 159 + return -EINVAL; 160 + 161 + temp = srate / 1000; 162 + temp *= 11831; 163 + temp /= 68; 164 + temp -= 3; 165 + 166 + b[0] = (u8) (temp >> 16) & 0xff; 167 + b[1] = (u8) (temp >> 8) & 0xff; 168 + b[2] = (u8) temp & 0xff; 169 + ret = m88rs2000_demod_write(state, 0x93, b[2]); 170 + ret |= m88rs2000_demod_write(state, 0x94, b[1]); 171 + ret |= m88rs2000_demod_write(state, 0x95, b[0]); 172 + 173 + deb_info("m88rs2000: m88rs2000_set_symbolrate\n"); 174 + return ret; 175 + } 176 + 177 + static int m88rs2000_send_diseqc_msg(struct dvb_frontend *fe, 178 + struct dvb_diseqc_master_cmd *m) 179 + { 180 + struct m88rs2000_state *state = fe->demodulator_priv; 181 + 182 + int i; 183 + u8 reg; 184 + deb_info("%s\n", __func__); 185 + m88rs2000_demod_write(state, 0x9a, 0x30); 186 + reg = m88rs2000_demod_read(state, 0xb2); 187 + reg &= 0x3f; 188 + m88rs2000_demod_write(state, 0xb2, reg); 189 + for (i = 0; i < m->msg_len; i++) 190 + m88rs2000_demod_write(state, 0xb3 + i, m->msg[i]); 191 + 192 + reg = m88rs2000_demod_read(state, 0xb1); 193 + reg &= 0x87; 194 + reg |= ((m->msg_len - 1) << 3) | 0x07; 195 + reg &= 0x7f; 196 + m88rs2000_demod_write(state, 0xb1, reg); 197 + 198 + for (i = 0; i < 15; i++) { 199 + if ((m88rs2000_demod_read(state, 0xb1) & 0x40) == 0x0) 200 + break; 201 + msleep(20); 202 + } 203 + 204 + reg = m88rs2000_demod_read(state, 0xb1); 205 + if ((reg & 0x40) > 0x0) { 206 + reg &= 0x7f; 207 + reg |= 0x40; 208 + m88rs2000_demod_write(state, 0xb1, reg); 209 + } 210 + 211 + reg = m88rs2000_demod_read(state, 0xb2); 212 + reg &= 0x3f; 213 + reg |= 0x80; 214 + m88rs2000_demod_write(state, 0xb2, reg); 215 + m88rs2000_demod_write(state, 0x9a, 0xb0); 216 + 217 + 218 + return 0; 219 + } 220 + 221 + static int m88rs2000_send_diseqc_burst(struct dvb_frontend *fe, 222 + fe_sec_mini_cmd_t burst) 223 + { 224 + struct m88rs2000_state *state = fe->demodulator_priv; 225 + u8 reg0, reg1; 226 + deb_info("%s\n", __func__); 227 + m88rs2000_demod_write(state, 0x9a, 0x30); 228 + msleep(50); 229 + reg0 = m88rs2000_demod_read(state, 0xb1); 230 + reg1 = m88rs2000_demod_read(state, 0xb2); 231 + /* TODO complete this section */ 232 + m88rs2000_demod_write(state, 0xb2, reg1); 233 + m88rs2000_demod_write(state, 0xb1, reg0); 234 + m88rs2000_demod_write(state, 0x9a, 0xb0); 235 + 236 + return 0; 237 + } 238 + 239 + static int m88rs2000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) 240 + { 241 + struct m88rs2000_state *state = fe->demodulator_priv; 242 + u8 reg0, reg1; 243 + m88rs2000_demod_write(state, 0x9a, 0x30); 244 + reg0 = m88rs2000_demod_read(state, 0xb1); 245 + reg1 = m88rs2000_demod_read(state, 0xb2); 246 + 247 + reg1 &= 0x3f; 248 + 249 + switch (tone) { 250 + case SEC_TONE_ON: 251 + reg0 |= 0x4; 252 + reg0 &= 0xbc; 253 + break; 254 + case SEC_TONE_OFF: 255 + reg1 |= 0x80; 256 + break; 257 + default: 258 + break; 259 + } 260 + m88rs2000_demod_write(state, 0xb2, reg1); 261 + m88rs2000_demod_write(state, 0xb1, reg0); 262 + m88rs2000_demod_write(state, 0x9a, 0xb0); 263 + return 0; 264 + } 265 + 266 + struct inittab { 267 + u8 cmd; 268 + u8 reg; 269 + u8 val; 270 + }; 271 + 272 + struct inittab m88rs2000_setup[] = { 273 + {DEMOD_WRITE, 0x9a, 0x30}, 274 + {DEMOD_WRITE, 0x00, 0x01}, 275 + {WRITE_DELAY, 0x19, 0x00}, 276 + {DEMOD_WRITE, 0x00, 0x00}, 277 + {DEMOD_WRITE, 0x9a, 0xb0}, 278 + {DEMOD_WRITE, 0x81, 0xc1}, 279 + {TUNER_WRITE, 0x42, 0x73}, 280 + {TUNER_WRITE, 0x05, 0x07}, 281 + {TUNER_WRITE, 0x20, 0x27}, 282 + {TUNER_WRITE, 0x07, 0x02}, 283 + {TUNER_WRITE, 0x11, 0xff}, 284 + {TUNER_WRITE, 0x60, 0xf9}, 285 + {TUNER_WRITE, 0x08, 0x01}, 286 + {TUNER_WRITE, 0x00, 0x41}, 287 + {DEMOD_WRITE, 0x81, 0x81}, 288 + {DEMOD_WRITE, 0x86, 0xc6}, 289 + {DEMOD_WRITE, 0x9a, 0x30}, 290 + {DEMOD_WRITE, 0xf0, 0x22}, 291 + {DEMOD_WRITE, 0xf1, 0xbf}, 292 + {DEMOD_WRITE, 0xb0, 0x45}, 293 + {DEMOD_WRITE, 0xb2, 0x01}, /* set voltage pin always set 1*/ 294 + {DEMOD_WRITE, 0x9a, 0xb0}, 295 + {0xff, 0xaa, 0xff} 296 + }; 297 + 298 + struct inittab m88rs2000_shutdown[] = { 299 + {DEMOD_WRITE, 0x9a, 0x30}, 300 + {DEMOD_WRITE, 0xb0, 0x00}, 301 + {DEMOD_WRITE, 0xf1, 0x89}, 302 + {DEMOD_WRITE, 0x00, 0x01}, 303 + {DEMOD_WRITE, 0x9a, 0xb0}, 304 + {TUNER_WRITE, 0x00, 0x40}, 305 + {DEMOD_WRITE, 0x81, 0x81}, 306 + {0xff, 0xaa, 0xff} 307 + }; 308 + 309 + struct inittab tuner_reset[] = { 310 + {TUNER_WRITE, 0x42, 0x73}, 311 + {TUNER_WRITE, 0x05, 0x07}, 312 + {TUNER_WRITE, 0x20, 0x27}, 313 + {TUNER_WRITE, 0x07, 0x02}, 314 + {TUNER_WRITE, 0x11, 0xff}, 315 + {TUNER_WRITE, 0x60, 0xf9}, 316 + {TUNER_WRITE, 0x08, 0x01}, 317 + {TUNER_WRITE, 0x00, 0x41}, 318 + {0xff, 0xaa, 0xff} 319 + }; 320 + 321 + struct inittab fe_reset[] = { 322 + {DEMOD_WRITE, 0x00, 0x01}, 323 + {DEMOD_WRITE, 0xf1, 0xbf}, 324 + {DEMOD_WRITE, 0x00, 0x01}, 325 + {DEMOD_WRITE, 0x20, 0x81}, 326 + {DEMOD_WRITE, 0x21, 0x80}, 327 + {DEMOD_WRITE, 0x10, 0x33}, 328 + {DEMOD_WRITE, 0x11, 0x44}, 329 + {DEMOD_WRITE, 0x12, 0x07}, 330 + {DEMOD_WRITE, 0x18, 0x20}, 331 + {DEMOD_WRITE, 0x28, 0x04}, 332 + {DEMOD_WRITE, 0x29, 0x8e}, 333 + {DEMOD_WRITE, 0x3b, 0xff}, 334 + {DEMOD_WRITE, 0x32, 0x10}, 335 + {DEMOD_WRITE, 0x33, 0x02}, 336 + {DEMOD_WRITE, 0x34, 0x30}, 337 + {DEMOD_WRITE, 0x35, 0xff}, 338 + {DEMOD_WRITE, 0x38, 0x50}, 339 + {DEMOD_WRITE, 0x39, 0x68}, 340 + {DEMOD_WRITE, 0x3c, 0x7f}, 341 + {DEMOD_WRITE, 0x3d, 0x0f}, 342 + {DEMOD_WRITE, 0x45, 0x20}, 343 + {DEMOD_WRITE, 0x46, 0x24}, 344 + {DEMOD_WRITE, 0x47, 0x7c}, 345 + {DEMOD_WRITE, 0x48, 0x16}, 346 + {DEMOD_WRITE, 0x49, 0x04}, 347 + {DEMOD_WRITE, 0x4a, 0x01}, 348 + {DEMOD_WRITE, 0x4b, 0x78}, 349 + {DEMOD_WRITE, 0X4d, 0xd2}, 350 + {DEMOD_WRITE, 0x4e, 0x6d}, 351 + {DEMOD_WRITE, 0x50, 0x30}, 352 + {DEMOD_WRITE, 0x51, 0x30}, 353 + {DEMOD_WRITE, 0x54, 0x7b}, 354 + {DEMOD_WRITE, 0x56, 0x09}, 355 + {DEMOD_WRITE, 0x58, 0x59}, 356 + {DEMOD_WRITE, 0x59, 0x37}, 357 + {DEMOD_WRITE, 0x63, 0xfa}, 358 + {0xff, 0xaa, 0xff} 359 + }; 360 + 361 + struct inittab fe_trigger[] = { 362 + {DEMOD_WRITE, 0x97, 0x04}, 363 + {DEMOD_WRITE, 0x99, 0x77}, 364 + {DEMOD_WRITE, 0x9b, 0x64}, 365 + {DEMOD_WRITE, 0x9e, 0x00}, 366 + {DEMOD_WRITE, 0x9f, 0xf8}, 367 + {DEMOD_WRITE, 0xa0, 0x20}, 368 + {DEMOD_WRITE, 0xa1, 0xe0}, 369 + {DEMOD_WRITE, 0xa3, 0x38}, 370 + {DEMOD_WRITE, 0x98, 0xff}, 371 + {DEMOD_WRITE, 0xc0, 0x0f}, 372 + {DEMOD_WRITE, 0x89, 0x01}, 373 + {DEMOD_WRITE, 0x00, 0x00}, 374 + {WRITE_DELAY, 0x0a, 0x00}, 375 + {DEMOD_WRITE, 0x00, 0x01}, 376 + {DEMOD_WRITE, 0x00, 0x00}, 377 + {DEMOD_WRITE, 0x9a, 0xb0}, 378 + {0xff, 0xaa, 0xff} 379 + }; 380 + 381 + static int m88rs2000_tab_set(struct m88rs2000_state *state, 382 + struct inittab *tab) 383 + { 384 + int ret = 0; 385 + u8 i; 386 + if (tab == NULL) 387 + return -EINVAL; 388 + 389 + for (i = 0; i < 255; i++) { 390 + switch (tab[i].cmd) { 391 + case 0x01: 392 + ret = m88rs2000_demod_write(state, tab[i].reg, 393 + tab[i].val); 394 + break; 395 + case 0x02: 396 + ret = m88rs2000_tuner_write(state, tab[i].reg, 397 + tab[i].val); 398 + break; 399 + case 0x10: 400 + if (tab[i].reg > 0) 401 + mdelay(tab[i].reg); 402 + break; 403 + case 0xff: 404 + if (tab[i].reg == 0xaa && tab[i].val == 0xff) 405 + return 0; 406 + case 0x00: 407 + break; 408 + default: 409 + return -EINVAL; 410 + } 411 + if (ret < 0) 412 + return -ENODEV; 413 + } 414 + return 0; 415 + } 416 + 417 + static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) 418 + { 419 + deb_info("%s: %s\n", __func__, 420 + volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : 421 + volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); 422 + 423 + return 0; 424 + } 425 + 426 + static int m88rs2000_startup(struct m88rs2000_state *state) 427 + { 428 + int ret = 0; 429 + u8 reg; 430 + 431 + reg = m88rs2000_tuner_read(state, 0x00); 432 + if ((reg & 0x40) == 0) 433 + ret = -ENODEV; 434 + 435 + return ret; 436 + } 437 + 438 + static int m88rs2000_init(struct dvb_frontend *fe) 439 + { 440 + struct m88rs2000_state *state = fe->demodulator_priv; 441 + int ret; 442 + 443 + deb_info("m88rs2000: init chip\n"); 444 + /* Setup frontend from shutdown/cold */ 445 + ret = m88rs2000_tab_set(state, m88rs2000_setup); 446 + 447 + return ret; 448 + } 449 + 450 + static int m88rs2000_sleep(struct dvb_frontend *fe) 451 + { 452 + struct m88rs2000_state *state = fe->demodulator_priv; 453 + int ret; 454 + /* Shutdown the frondend */ 455 + ret = m88rs2000_tab_set(state, m88rs2000_shutdown); 456 + return ret; 457 + } 458 + 459 + static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status) 460 + { 461 + struct m88rs2000_state *state = fe->demodulator_priv; 462 + u8 reg = m88rs2000_demod_read(state, 0x8c); 463 + 464 + *status = 0; 465 + 466 + if ((reg & 0x7) == 0x7) { 467 + *status = FE_HAS_CARRIER | FE_HAS_SIGNAL | FE_HAS_VITERBI 468 + | FE_HAS_LOCK; 469 + if (state->config->set_ts_params) 470 + state->config->set_ts_params(fe, CALL_IS_READ); 471 + } 472 + return 0; 473 + } 474 + 475 + /* Extact code for these unknown but lmedm04 driver uses interupt callbacks */ 476 + 477 + static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber) 478 + { 479 + deb_info("m88rs2000_read_ber %d\n", *ber); 480 + *ber = 0; 481 + return 0; 482 + } 483 + 484 + static int m88rs2000_read_signal_strength(struct dvb_frontend *fe, 485 + u16 *strength) 486 + { 487 + *strength = 0; 488 + return 0; 489 + } 490 + 491 + static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr) 492 + { 493 + deb_info("m88rs2000_read_snr %d\n", *snr); 494 + *snr = 0; 495 + return 0; 496 + } 497 + 498 + static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 499 + { 500 + deb_info("m88rs2000_read_ber %d\n", *ucblocks); 501 + *ucblocks = 0; 502 + return 0; 503 + } 504 + 505 + static int m88rs2000_tuner_gate_ctrl(struct m88rs2000_state *state, u8 offset) 506 + { 507 + int ret; 508 + ret = m88rs2000_tuner_write(state, 0x51, 0x1f - offset); 509 + ret |= m88rs2000_tuner_write(state, 0x51, 0x1f); 510 + ret |= m88rs2000_tuner_write(state, 0x50, offset); 511 + ret |= m88rs2000_tuner_write(state, 0x50, 0x00); 512 + msleep(20); 513 + return ret; 514 + } 515 + 516 + static int m88rs2000_set_tuner_rf(struct dvb_frontend *fe) 517 + { 518 + struct m88rs2000_state *state = fe->demodulator_priv; 519 + int reg; 520 + reg = m88rs2000_tuner_read(state, 0x3d); 521 + reg &= 0x7f; 522 + if (reg < 0x16) 523 + reg = 0xa1; 524 + else if (reg == 0x16) 525 + reg = 0x99; 526 + else 527 + reg = 0xf9; 528 + 529 + m88rs2000_tuner_write(state, 0x60, reg); 530 + reg = m88rs2000_tuner_gate_ctrl(state, 0x08); 531 + 532 + if (fe->ops.i2c_gate_ctrl) 533 + fe->ops.i2c_gate_ctrl(fe, 0); 534 + return reg; 535 + } 536 + 537 + static int m88rs2000_set_tuner(struct dvb_frontend *fe, u16 *offset) 538 + { 539 + struct dtv_frontend_properties *c = &fe->dtv_property_cache; 540 + struct m88rs2000_state *state = fe->demodulator_priv; 541 + int ret; 542 + u32 frequency = c->frequency; 543 + s32 offset_khz; 544 + s32 tmp; 545 + u32 symbol_rate = (c->symbol_rate / 1000); 546 + u32 f3db, gdiv28; 547 + u16 value, ndiv, lpf_coeff; 548 + u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf; 549 + u8 lo = 0x01, div4 = 0x0; 550 + 551 + /* Reset Tuner */ 552 + ret = m88rs2000_tab_set(state, tuner_reset); 553 + 554 + /* Calculate frequency divider */ 555 + if (frequency < 1060000) { 556 + lo |= 0x10; 557 + div4 = 0x1; 558 + ndiv = (frequency * 14 * 4) / FE_CRYSTAL_KHZ; 559 + } else 560 + ndiv = (frequency * 14 * 2) / FE_CRYSTAL_KHZ; 561 + ndiv = ndiv + ndiv % 2; 562 + ndiv = ndiv - 1024; 563 + 564 + ret = m88rs2000_tuner_write(state, 0x10, 0x80 | lo); 565 + 566 + /* Set frequency divider */ 567 + ret |= m88rs2000_tuner_write(state, 0x01, (ndiv >> 8) & 0xf); 568 + ret |= m88rs2000_tuner_write(state, 0x02, ndiv & 0xff); 569 + 570 + ret |= m88rs2000_tuner_write(state, 0x03, 0x06); 571 + ret |= m88rs2000_tuner_gate_ctrl(state, 0x10); 572 + if (ret < 0) 573 + return -ENODEV; 574 + 575 + /* Tuner Frequency Range */ 576 + ret = m88rs2000_tuner_write(state, 0x10, lo); 577 + 578 + ret |= m88rs2000_tuner_gate_ctrl(state, 0x08); 579 + 580 + /* Tuner RF */ 581 + ret |= m88rs2000_set_tuner_rf(fe); 582 + 583 + gdiv28 = (FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000; 584 + ret |= m88rs2000_tuner_write(state, 0x04, gdiv28 & 0xff); 585 + ret |= m88rs2000_tuner_gate_ctrl(state, 0x04); 586 + if (ret < 0) 587 + return -ENODEV; 588 + 589 + value = m88rs2000_tuner_read(state, 0x26); 590 + 591 + f3db = (symbol_rate * 135) / 200 + 2000; 592 + f3db += FREQ_OFFSET_LOW_SYM_RATE; 593 + if (f3db < 7000) 594 + f3db = 7000; 595 + if (f3db > 40000) 596 + f3db = 40000; 597 + 598 + gdiv28 = gdiv28 * 207 / (value * 2 + 151); 599 + mlpf_max = gdiv28 * 135 / 100; 600 + mlpf_min = gdiv28 * 78 / 100; 601 + if (mlpf_max > 63) 602 + mlpf_max = 63; 603 + 604 + lpf_coeff = 2766; 605 + 606 + nlpf = (f3db * gdiv28 * 2 / lpf_coeff / 607 + (FE_CRYSTAL_KHZ / 1000) + 1) / 2; 608 + if (nlpf > 23) 609 + nlpf = 23; 610 + if (nlpf < 1) 611 + nlpf = 1; 612 + 613 + lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000) 614 + * lpf_coeff * 2 / f3db + 1) / 2; 615 + 616 + if (lpf_mxdiv < mlpf_min) { 617 + nlpf++; 618 + lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000) 619 + * lpf_coeff * 2 / f3db + 1) / 2; 620 + } 621 + 622 + if (lpf_mxdiv > mlpf_max) 623 + lpf_mxdiv = mlpf_max; 624 + 625 + ret = m88rs2000_tuner_write(state, 0x04, lpf_mxdiv); 626 + ret |= m88rs2000_tuner_write(state, 0x06, nlpf); 627 + 628 + ret |= m88rs2000_tuner_gate_ctrl(state, 0x04); 629 + 630 + ret |= m88rs2000_tuner_gate_ctrl(state, 0x01); 631 + 632 + msleep(80); 633 + /* calculate offset assuming 96000kHz*/ 634 + offset_khz = (ndiv - ndiv % 2 + 1024) * FE_CRYSTAL_KHZ 635 + / 14 / (div4 + 1) / 2; 636 + 637 + offset_khz -= frequency; 638 + 639 + tmp = offset_khz; 640 + tmp *= 65536; 641 + 642 + tmp = (2 * tmp + 96000) / (2 * 96000); 643 + if (tmp < 0) 644 + tmp += 65536; 645 + 646 + *offset = tmp & 0xffff; 647 + 648 + if (fe->ops.i2c_gate_ctrl) 649 + fe->ops.i2c_gate_ctrl(fe, 0); 650 + 651 + return (ret < 0) ? -EINVAL : 0; 652 + } 653 + 654 + static int m88rs2000_set_fec(struct m88rs2000_state *state, 655 + fe_code_rate_t fec) 656 + { 657 + int ret; 658 + u16 fec_set; 659 + switch (fec) { 660 + /* This is not confirmed kept for reference */ 661 + /* case FEC_1_2: 662 + fec_set = 0x88; 663 + break; 664 + case FEC_2_3: 665 + fec_set = 0x68; 666 + break; 667 + case FEC_3_4: 668 + fec_set = 0x48; 669 + break; 670 + case FEC_5_6: 671 + fec_set = 0x28; 672 + break; 673 + case FEC_7_8: 674 + fec_set = 0x18; 675 + break; */ 676 + case FEC_AUTO: 677 + default: 678 + fec_set = 0x08; 679 + } 680 + ret = m88rs2000_demod_write(state, 0x76, fec_set); 681 + 682 + return 0; 683 + } 684 + 685 + 686 + static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state) 687 + { 688 + u8 reg; 689 + m88rs2000_demod_write(state, 0x9a, 0x30); 690 + reg = m88rs2000_demod_read(state, 0x76); 691 + m88rs2000_demod_write(state, 0x9a, 0xb0); 692 + 693 + switch (reg) { 694 + case 0x88: 695 + return FEC_1_2; 696 + case 0x68: 697 + return FEC_2_3; 698 + case 0x48: 699 + return FEC_3_4; 700 + case 0x28: 701 + return FEC_5_6; 702 + case 0x18: 703 + return FEC_7_8; 704 + case 0x08: 705 + default: 706 + break; 707 + } 708 + 709 + return FEC_AUTO; 710 + } 711 + 712 + static int m88rs2000_set_frontend(struct dvb_frontend *fe) 713 + { 714 + struct m88rs2000_state *state = fe->demodulator_priv; 715 + struct dtv_frontend_properties *c = &fe->dtv_property_cache; 716 + fe_status_t status; 717 + int i, ret; 718 + u16 offset = 0; 719 + u8 reg; 720 + 721 + state->no_lock_count = 0; 722 + 723 + if (c->delivery_system != SYS_DVBS) { 724 + deb_info("%s: unsupported delivery " 725 + "system selected (%d)\n", 726 + __func__, c->delivery_system); 727 + return -EOPNOTSUPP; 728 + } 729 + 730 + /* Set Tuner */ 731 + ret = m88rs2000_set_tuner(fe, &offset); 732 + if (ret < 0) 733 + return -ENODEV; 734 + 735 + ret = m88rs2000_demod_write(state, 0x9a, 0x30); 736 + /* Unknown usually 0xc6 sometimes 0xc1 */ 737 + reg = m88rs2000_demod_read(state, 0x86); 738 + ret |= m88rs2000_demod_write(state, 0x86, reg); 739 + /* Offset lower nibble always 0 */ 740 + ret |= m88rs2000_demod_write(state, 0x9c, (offset >> 8)); 741 + ret |= m88rs2000_demod_write(state, 0x9d, offset & 0xf0); 742 + 743 + 744 + /* Reset Demod */ 745 + ret = m88rs2000_tab_set(state, fe_reset); 746 + if (ret < 0) 747 + return -ENODEV; 748 + 749 + /* Unknown */ 750 + reg = m88rs2000_demod_read(state, 0x70); 751 + ret = m88rs2000_demod_write(state, 0x70, reg); 752 + 753 + /* Set FEC */ 754 + ret |= m88rs2000_set_fec(state, c->fec_inner); 755 + ret |= m88rs2000_demod_write(state, 0x85, 0x1); 756 + ret |= m88rs2000_demod_write(state, 0x8a, 0xbf); 757 + ret |= m88rs2000_demod_write(state, 0x8d, 0x1e); 758 + ret |= m88rs2000_demod_write(state, 0x90, 0xf1); 759 + ret |= m88rs2000_demod_write(state, 0x91, 0x08); 760 + 761 + if (ret < 0) 762 + return -ENODEV; 763 + 764 + /* Set Symbol Rate */ 765 + ret = m88rs2000_set_symbolrate(fe, c->symbol_rate); 766 + if (ret < 0) 767 + return -ENODEV; 768 + 769 + /* Set up Demod */ 770 + ret = m88rs2000_tab_set(state, fe_trigger); 771 + if (ret < 0) 772 + return -ENODEV; 773 + 774 + for (i = 0; i < 25; i++) { 775 + u8 reg = m88rs2000_demod_read(state, 0x8c); 776 + if ((reg & 0x7) == 0x7) { 777 + status = FE_HAS_LOCK; 778 + break; 779 + } 780 + state->no_lock_count++; 781 + if (state->no_lock_count > 15) { 782 + reg = m88rs2000_demod_read(state, 0x70); 783 + reg ^= 0x4; 784 + m88rs2000_demod_write(state, 0x70, reg); 785 + state->no_lock_count = 0; 786 + } 787 + if (state->no_lock_count == 20) 788 + m88rs2000_set_tuner_rf(fe); 789 + msleep(20); 790 + } 791 + 792 + if (status & FE_HAS_LOCK) { 793 + state->fec_inner = m88rs2000_get_fec(state); 794 + /* Uknown suspect SNR level */ 795 + reg = m88rs2000_demod_read(state, 0x65); 796 + } 797 + 798 + state->tuner_frequency = c->frequency; 799 + state->symbol_rate = c->symbol_rate; 800 + return 0; 801 + } 802 + 803 + static int m88rs2000_get_frontend(struct dvb_frontend *fe) 804 + { 805 + struct dtv_frontend_properties *c = &fe->dtv_property_cache; 806 + struct m88rs2000_state *state = fe->demodulator_priv; 807 + c->fec_inner = state->fec_inner; 808 + c->frequency = state->tuner_frequency; 809 + c->symbol_rate = state->symbol_rate; 810 + return 0; 811 + } 812 + 813 + static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 814 + { 815 + struct m88rs2000_state *state = fe->demodulator_priv; 816 + 817 + if (enable) 818 + m88rs2000_demod_write(state, 0x81, 0x84); 819 + else 820 + m88rs2000_demod_write(state, 0x81, 0x81); 821 + udelay(10); 822 + return 0; 823 + } 824 + 825 + static void m88rs2000_release(struct dvb_frontend *fe) 826 + { 827 + struct m88rs2000_state *state = fe->demodulator_priv; 828 + kfree(state); 829 + } 830 + 831 + static struct dvb_frontend_ops m88rs2000_ops = { 832 + .delsys = { SYS_DVBS }, 833 + .info = { 834 + .name = "M88RS2000 DVB-S", 835 + .frequency_min = 950000, 836 + .frequency_max = 2150000, 837 + .frequency_stepsize = 1000, /* kHz for QPSK frontends */ 838 + .frequency_tolerance = 5000, 839 + .symbol_rate_min = 1000000, 840 + .symbol_rate_max = 45000000, 841 + .symbol_rate_tolerance = 500, /* ppm */ 842 + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 843 + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | 844 + FE_CAN_QPSK | 845 + FE_CAN_FEC_AUTO 846 + }, 847 + 848 + .release = m88rs2000_release, 849 + .init = m88rs2000_init, 850 + .sleep = m88rs2000_sleep, 851 + .write = m88rs2000_write, 852 + .i2c_gate_ctrl = m88rs2000_i2c_gate_ctrl, 853 + .read_status = m88rs2000_read_status, 854 + .read_ber = m88rs2000_read_ber, 855 + .read_signal_strength = m88rs2000_read_signal_strength, 856 + .read_snr = m88rs2000_read_snr, 857 + .read_ucblocks = m88rs2000_read_ucblocks, 858 + .diseqc_send_master_cmd = m88rs2000_send_diseqc_msg, 859 + .diseqc_send_burst = m88rs2000_send_diseqc_burst, 860 + .set_tone = m88rs2000_set_tone, 861 + .set_voltage = m88rs2000_set_voltage, 862 + 863 + .set_frontend = m88rs2000_set_frontend, 864 + .get_frontend = m88rs2000_get_frontend, 865 + }; 866 + 867 + struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config, 868 + struct i2c_adapter *i2c) 869 + { 870 + struct m88rs2000_state *state = NULL; 871 + 872 + /* allocate memory for the internal state */ 873 + state = kzalloc(sizeof(struct m88rs2000_state), GFP_KERNEL); 874 + if (state == NULL) 875 + goto error; 876 + 877 + /* setup the state */ 878 + state->config = config; 879 + state->i2c = i2c; 880 + state->tuner_frequency = 0; 881 + state->symbol_rate = 0; 882 + state->fec_inner = 0; 883 + 884 + if (m88rs2000_startup(state) < 0) 885 + goto error; 886 + 887 + /* create dvb_frontend */ 888 + memcpy(&state->frontend.ops, &m88rs2000_ops, 889 + sizeof(struct dvb_frontend_ops)); 890 + state->frontend.demodulator_priv = state; 891 + return &state->frontend; 892 + 893 + error: 894 + kfree(state); 895 + 896 + return NULL; 897 + } 898 + EXPORT_SYMBOL(m88rs2000_attach); 899 + 900 + MODULE_DESCRIPTION("M88RS2000 DVB-S Demodulator driver"); 901 + MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); 902 + MODULE_LICENSE("GPL"); 903 + MODULE_VERSION("1.13"); 904 +
+66
drivers/media/dvb/frontends/m88rs2000.h
··· 1 + /* 2 + Driver for M88RS2000 demodulator 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; either version 2 of the License, or 7 + (at your option) any later version. 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. 13 + 14 + You should have received a copy of the GNU General Public License 15 + along with this program; if not, write to the Free Software 16 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 + 18 + */ 19 + 20 + #ifndef M88RS2000_H 21 + #define M88RS2000_H 22 + 23 + #include <linux/dvb/frontend.h> 24 + #include "dvb_frontend.h" 25 + 26 + struct m88rs2000_config { 27 + /* Demodulator i2c address */ 28 + u8 demod_addr; 29 + /* Tuner address */ 30 + u8 tuner_addr; 31 + 32 + u8 *inittab; 33 + 34 + /* minimum delay before retuning */ 35 + int min_delay_ms; 36 + 37 + int (*set_ts_params)(struct dvb_frontend *, int); 38 + }; 39 + 40 + enum { 41 + CALL_IS_SET_FRONTEND = 0x0, 42 + CALL_IS_READ, 43 + }; 44 + 45 + #if defined(CONFIG_DVB_M88RS2000) || (defined(CONFIG_DVB_M88RS2000_MODULE) && \ 46 + defined(MODULE)) 47 + extern struct dvb_frontend *m88rs2000_attach( 48 + const struct m88rs2000_config *config, struct i2c_adapter *i2c); 49 + #else 50 + static inline struct dvb_frontend *m88rs2000_attach( 51 + const struct m88rs2000_config *config, struct i2c_adapter *i2c) 52 + { 53 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 54 + return NULL; 55 + } 56 + #endif /* CONFIG_DVB_M88RS2000 */ 57 + 58 + #define FE_CRYSTAL_KHZ 27000 59 + #define FREQ_OFFSET_LOW_SYM_RATE 3000 60 + 61 + enum { 62 + DEMOD_WRITE = 0x1, 63 + TUNER_WRITE, 64 + WRITE_DELAY = 0x10, 65 + }; 66 + #endif /* M88RS2000_H */
+562
drivers/media/dvb/frontends/rtl2830.c
··· 1 + /* 2 + * Realtek RTL2830 DVB-T demodulator driver 3 + * 4 + * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> 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 as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along 17 + * with this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 + */ 20 + 21 + 22 + /* 23 + * Driver implements own I2C-adapter for tuner I2C access. That's since chip 24 + * have unusual I2C-gate control which closes gate automatically after each 25 + * I2C transfer. Using own I2C adapter we can workaround that. 26 + */ 27 + 28 + #include "rtl2830_priv.h" 29 + 30 + int rtl2830_debug; 31 + module_param_named(debug, rtl2830_debug, int, 0644); 32 + MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 33 + 34 + /* write multiple hardware registers */ 35 + static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, u8 *val, int len) 36 + { 37 + int ret; 38 + u8 buf[1+len]; 39 + struct i2c_msg msg[1] = { 40 + { 41 + .addr = priv->cfg.i2c_addr, 42 + .flags = 0, 43 + .len = 1+len, 44 + .buf = buf, 45 + } 46 + }; 47 + 48 + buf[0] = reg; 49 + memcpy(&buf[1], val, len); 50 + 51 + ret = i2c_transfer(priv->i2c, msg, 1); 52 + if (ret == 1) { 53 + ret = 0; 54 + } else { 55 + warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len); 56 + ret = -EREMOTEIO; 57 + } 58 + return ret; 59 + } 60 + 61 + /* read multiple hardware registers */ 62 + static int rtl2830_rd(struct rtl2830_priv *priv, u8 reg, u8 *val, int len) 63 + { 64 + int ret; 65 + struct i2c_msg msg[2] = { 66 + { 67 + .addr = priv->cfg.i2c_addr, 68 + .flags = 0, 69 + .len = 1, 70 + .buf = &reg, 71 + }, { 72 + .addr = priv->cfg.i2c_addr, 73 + .flags = I2C_M_RD, 74 + .len = len, 75 + .buf = val, 76 + } 77 + }; 78 + 79 + ret = i2c_transfer(priv->i2c, msg, 2); 80 + if (ret == 2) { 81 + ret = 0; 82 + } else { 83 + warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len); 84 + ret = -EREMOTEIO; 85 + } 86 + return ret; 87 + } 88 + 89 + /* write multiple registers */ 90 + static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len) 91 + { 92 + int ret; 93 + u8 reg2 = (reg >> 0) & 0xff; 94 + u8 page = (reg >> 8) & 0xff; 95 + 96 + /* switch bank if needed */ 97 + if (page != priv->page) { 98 + ret = rtl2830_wr(priv, 0x00, &page, 1); 99 + if (ret) 100 + return ret; 101 + 102 + priv->page = page; 103 + } 104 + 105 + return rtl2830_wr(priv, reg2, val, len); 106 + } 107 + 108 + /* read multiple registers */ 109 + static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len) 110 + { 111 + int ret; 112 + u8 reg2 = (reg >> 0) & 0xff; 113 + u8 page = (reg >> 8) & 0xff; 114 + 115 + /* switch bank if needed */ 116 + if (page != priv->page) { 117 + ret = rtl2830_wr(priv, 0x00, &page, 1); 118 + if (ret) 119 + return ret; 120 + 121 + priv->page = page; 122 + } 123 + 124 + return rtl2830_rd(priv, reg2, val, len); 125 + } 126 + 127 + #if 0 /* currently not used */ 128 + /* write single register */ 129 + static int rtl2830_wr_reg(struct rtl2830_priv *priv, u16 reg, u8 val) 130 + { 131 + return rtl2830_wr_regs(priv, reg, &val, 1); 132 + } 133 + #endif 134 + 135 + /* read single register */ 136 + static int rtl2830_rd_reg(struct rtl2830_priv *priv, u16 reg, u8 *val) 137 + { 138 + return rtl2830_rd_regs(priv, reg, val, 1); 139 + } 140 + 141 + /* write single register with mask */ 142 + int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask) 143 + { 144 + int ret; 145 + u8 tmp; 146 + 147 + /* no need for read if whole reg is written */ 148 + if (mask != 0xff) { 149 + ret = rtl2830_rd_regs(priv, reg, &tmp, 1); 150 + if (ret) 151 + return ret; 152 + 153 + val &= mask; 154 + tmp &= ~mask; 155 + val |= tmp; 156 + } 157 + 158 + return rtl2830_wr_regs(priv, reg, &val, 1); 159 + } 160 + 161 + /* read single register with mask */ 162 + int rtl2830_rd_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 *val, u8 mask) 163 + { 164 + int ret, i; 165 + u8 tmp; 166 + 167 + ret = rtl2830_rd_regs(priv, reg, &tmp, 1); 168 + if (ret) 169 + return ret; 170 + 171 + tmp &= mask; 172 + 173 + /* find position of the first bit */ 174 + for (i = 0; i < 8; i++) { 175 + if ((mask >> i) & 0x01) 176 + break; 177 + } 178 + *val = tmp >> i; 179 + 180 + return 0; 181 + } 182 + 183 + static int rtl2830_init(struct dvb_frontend *fe) 184 + { 185 + struct rtl2830_priv *priv = fe->demodulator_priv; 186 + int ret, i; 187 + u64 num; 188 + u8 buf[3], tmp; 189 + u32 if_ctl; 190 + struct rtl2830_reg_val_mask tab[] = { 191 + { 0x00d, 0x01, 0x03 }, 192 + { 0x00d, 0x10, 0x10 }, 193 + { 0x104, 0x00, 0x1e }, 194 + { 0x105, 0x80, 0x80 }, 195 + { 0x110, 0x02, 0x03 }, 196 + { 0x110, 0x08, 0x0c }, 197 + { 0x17b, 0x00, 0x40 }, 198 + { 0x17d, 0x05, 0x0f }, 199 + { 0x17d, 0x50, 0xf0 }, 200 + { 0x18c, 0x08, 0x0f }, 201 + { 0x18d, 0x00, 0xc0 }, 202 + { 0x188, 0x05, 0x0f }, 203 + { 0x189, 0x00, 0xfc }, 204 + { 0x2d5, 0x02, 0x02 }, 205 + { 0x2f1, 0x02, 0x06 }, 206 + { 0x2f1, 0x20, 0xf8 }, 207 + { 0x16d, 0x00, 0x01 }, 208 + { 0x1a6, 0x00, 0x80 }, 209 + { 0x106, priv->cfg.vtop, 0x3f }, 210 + { 0x107, priv->cfg.krf, 0x3f }, 211 + { 0x112, 0x28, 0xff }, 212 + { 0x103, priv->cfg.agc_targ_val, 0xff }, 213 + { 0x00a, 0x02, 0x07 }, 214 + { 0x140, 0x0c, 0x3c }, 215 + { 0x140, 0x40, 0xc0 }, 216 + { 0x15b, 0x05, 0x07 }, 217 + { 0x15b, 0x28, 0x38 }, 218 + { 0x15c, 0x05, 0x07 }, 219 + { 0x15c, 0x28, 0x38 }, 220 + { 0x115, priv->cfg.spec_inv, 0x01 }, 221 + { 0x16f, 0x01, 0x07 }, 222 + { 0x170, 0x18, 0x38 }, 223 + { 0x172, 0x0f, 0x0f }, 224 + { 0x173, 0x08, 0x38 }, 225 + { 0x175, 0x01, 0x07 }, 226 + { 0x176, 0x00, 0xc0 }, 227 + }; 228 + 229 + for (i = 0; i < ARRAY_SIZE(tab); i++) { 230 + ret = rtl2830_wr_reg_mask(priv, tab[i].reg, tab[i].val, 231 + tab[i].mask); 232 + if (ret) 233 + goto err; 234 + } 235 + 236 + ret = rtl2830_wr_regs(priv, 0x18f, "\x28\x00", 2); 237 + if (ret) 238 + goto err; 239 + 240 + ret = rtl2830_wr_regs(priv, 0x195, 241 + "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8); 242 + if (ret) 243 + goto err; 244 + 245 + num = priv->cfg.if_dvbt % priv->cfg.xtal; 246 + num *= 0x400000; 247 + num = div_u64(num, priv->cfg.xtal); 248 + num = -num; 249 + if_ctl = num & 0x3fffff; 250 + dbg("%s: if_ctl=%08x", __func__, if_ctl); 251 + 252 + ret = rtl2830_rd_reg_mask(priv, 0x119, &tmp, 0xc0); /* b[7:6] */ 253 + if (ret) 254 + goto err; 255 + 256 + buf[0] = tmp << 6; 257 + buf[0] = (if_ctl >> 16) & 0x3f; 258 + buf[1] = (if_ctl >> 8) & 0xff; 259 + buf[2] = (if_ctl >> 0) & 0xff; 260 + 261 + ret = rtl2830_wr_regs(priv, 0x119, buf, 3); 262 + if (ret) 263 + goto err; 264 + 265 + /* TODO: spec init */ 266 + 267 + /* soft reset */ 268 + ret = rtl2830_wr_reg_mask(priv, 0x101, 0x04, 0x04); 269 + if (ret) 270 + goto err; 271 + 272 + ret = rtl2830_wr_reg_mask(priv, 0x101, 0x00, 0x04); 273 + if (ret) 274 + goto err; 275 + 276 + priv->sleeping = false; 277 + 278 + return ret; 279 + err: 280 + dbg("%s: failed=%d", __func__, ret); 281 + return ret; 282 + } 283 + 284 + static int rtl2830_sleep(struct dvb_frontend *fe) 285 + { 286 + struct rtl2830_priv *priv = fe->demodulator_priv; 287 + priv->sleeping = true; 288 + return 0; 289 + } 290 + 291 + int rtl2830_get_tune_settings(struct dvb_frontend *fe, 292 + struct dvb_frontend_tune_settings *s) 293 + { 294 + s->min_delay_ms = 500; 295 + s->step_size = fe->ops.info.frequency_stepsize * 2; 296 + s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; 297 + 298 + return 0; 299 + } 300 + 301 + static int rtl2830_set_frontend(struct dvb_frontend *fe) 302 + { 303 + struct rtl2830_priv *priv = fe->demodulator_priv; 304 + struct dtv_frontend_properties *c = &fe->dtv_property_cache; 305 + int ret, i; 306 + static u8 bw_params1[3][34] = { 307 + { 308 + 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41, 309 + 0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a, 310 + 0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82, 311 + 0x03, 0x73, 0x03, 0xcf, /* 6 MHz */ 312 + }, { 313 + 0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca, 314 + 0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca, 315 + 0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e, 316 + 0x03, 0xd0, 0x04, 0x53, /* 7 MHz */ 317 + }, { 318 + 0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0, 319 + 0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a, 320 + 0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f, 321 + 0x04, 0x24, 0x04, 0xdb, /* 8 MHz */ 322 + }, 323 + }; 324 + static u8 bw_params2[3][6] = { 325 + {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30,}, /* 6 MHz */ 326 + {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98,}, /* 7 MHz */ 327 + {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64,}, /* 8 MHz */ 328 + }; 329 + 330 + 331 + dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__, 332 + c->frequency, c->bandwidth_hz, c->inversion); 333 + 334 + /* program tuner */ 335 + if (fe->ops.tuner_ops.set_params) 336 + fe->ops.tuner_ops.set_params(fe); 337 + 338 + switch (c->bandwidth_hz) { 339 + case 6000000: 340 + i = 0; 341 + break; 342 + case 7000000: 343 + i = 1; 344 + break; 345 + case 8000000: 346 + i = 2; 347 + break; 348 + default: 349 + dbg("invalid bandwidth"); 350 + return -EINVAL; 351 + } 352 + 353 + ret = rtl2830_wr_reg_mask(priv, 0x008, i << 1, 0x06); 354 + if (ret) 355 + goto err; 356 + 357 + /* 1/2 split I2C write */ 358 + ret = rtl2830_wr_regs(priv, 0x11c, &bw_params1[i][0], 17); 359 + if (ret) 360 + goto err; 361 + 362 + /* 2/2 split I2C write */ 363 + ret = rtl2830_wr_regs(priv, 0x12d, &bw_params1[i][17], 17); 364 + if (ret) 365 + goto err; 366 + 367 + ret = rtl2830_wr_regs(priv, 0x19d, bw_params2[i], 6); 368 + if (ret) 369 + goto err; 370 + 371 + return ret; 372 + err: 373 + dbg("%s: failed=%d", __func__, ret); 374 + return ret; 375 + } 376 + 377 + static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status) 378 + { 379 + struct rtl2830_priv *priv = fe->demodulator_priv; 380 + int ret; 381 + u8 tmp; 382 + *status = 0; 383 + 384 + if (priv->sleeping) 385 + return 0; 386 + 387 + ret = rtl2830_rd_reg_mask(priv, 0x351, &tmp, 0x78); /* [6:3] */ 388 + if (ret) 389 + goto err; 390 + 391 + if (tmp == 11) { 392 + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | 393 + FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 394 + } else if (tmp == 10) { 395 + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | 396 + FE_HAS_VITERBI; 397 + } 398 + 399 + return ret; 400 + err: 401 + dbg("%s: failed=%d", __func__, ret); 402 + return ret; 403 + } 404 + 405 + static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr) 406 + { 407 + *snr = 0; 408 + return 0; 409 + } 410 + 411 + static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber) 412 + { 413 + *ber = 0; 414 + return 0; 415 + } 416 + 417 + static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 418 + { 419 + *ucblocks = 0; 420 + return 0; 421 + } 422 + 423 + static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 424 + { 425 + *strength = 0; 426 + return 0; 427 + } 428 + 429 + static struct dvb_frontend_ops rtl2830_ops; 430 + 431 + static u32 rtl2830_tuner_i2c_func(struct i2c_adapter *adapter) 432 + { 433 + return I2C_FUNC_I2C; 434 + } 435 + 436 + static int rtl2830_tuner_i2c_xfer(struct i2c_adapter *i2c_adap, 437 + struct i2c_msg msg[], int num) 438 + { 439 + struct rtl2830_priv *priv = i2c_get_adapdata(i2c_adap); 440 + int ret; 441 + 442 + /* open i2c-gate */ 443 + ret = rtl2830_wr_reg_mask(priv, 0x101, 0x08, 0x08); 444 + if (ret) 445 + goto err; 446 + 447 + ret = i2c_transfer(priv->i2c, msg, num); 448 + if (ret < 0) 449 + warn("tuner i2c failed=%d", ret); 450 + 451 + return ret; 452 + err: 453 + dbg("%s: failed=%d", __func__, ret); 454 + return ret; 455 + } 456 + 457 + static struct i2c_algorithm rtl2830_tuner_i2c_algo = { 458 + .master_xfer = rtl2830_tuner_i2c_xfer, 459 + .functionality = rtl2830_tuner_i2c_func, 460 + }; 461 + 462 + struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(struct dvb_frontend *fe) 463 + { 464 + struct rtl2830_priv *priv = fe->demodulator_priv; 465 + return &priv->tuner_i2c_adapter; 466 + } 467 + EXPORT_SYMBOL(rtl2830_get_tuner_i2c_adapter); 468 + 469 + static void rtl2830_release(struct dvb_frontend *fe) 470 + { 471 + struct rtl2830_priv *priv = fe->demodulator_priv; 472 + 473 + i2c_del_adapter(&priv->tuner_i2c_adapter); 474 + kfree(priv); 475 + } 476 + 477 + struct dvb_frontend *rtl2830_attach(const struct rtl2830_config *cfg, 478 + struct i2c_adapter *i2c) 479 + { 480 + struct rtl2830_priv *priv = NULL; 481 + int ret = 0; 482 + u8 tmp; 483 + 484 + /* allocate memory for the internal state */ 485 + priv = kzalloc(sizeof(struct rtl2830_priv), GFP_KERNEL); 486 + if (priv == NULL) 487 + goto err; 488 + 489 + /* setup the priv */ 490 + priv->i2c = i2c; 491 + memcpy(&priv->cfg, cfg, sizeof(struct rtl2830_config)); 492 + 493 + /* check if the demod is there */ 494 + ret = rtl2830_rd_reg(priv, 0x000, &tmp); 495 + if (ret) 496 + goto err; 497 + 498 + /* create dvb_frontend */ 499 + memcpy(&priv->fe.ops, &rtl2830_ops, sizeof(struct dvb_frontend_ops)); 500 + priv->fe.demodulator_priv = priv; 501 + 502 + /* create tuner i2c adapter */ 503 + strlcpy(priv->tuner_i2c_adapter.name, "RTL2830 tuner I2C adapter", 504 + sizeof(priv->tuner_i2c_adapter.name)); 505 + priv->tuner_i2c_adapter.algo = &rtl2830_tuner_i2c_algo; 506 + priv->tuner_i2c_adapter.algo_data = NULL; 507 + i2c_set_adapdata(&priv->tuner_i2c_adapter, priv); 508 + if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) { 509 + err("tuner I2C bus could not be initialized"); 510 + goto err; 511 + } 512 + 513 + priv->sleeping = true; 514 + 515 + return &priv->fe; 516 + err: 517 + dbg("%s: failed=%d", __func__, ret); 518 + kfree(priv); 519 + return NULL; 520 + } 521 + EXPORT_SYMBOL(rtl2830_attach); 522 + 523 + static struct dvb_frontend_ops rtl2830_ops = { 524 + .delsys = { SYS_DVBT }, 525 + .info = { 526 + .name = "Realtek RTL2830 (DVB-T)", 527 + .caps = FE_CAN_FEC_1_2 | 528 + FE_CAN_FEC_2_3 | 529 + FE_CAN_FEC_3_4 | 530 + FE_CAN_FEC_5_6 | 531 + FE_CAN_FEC_7_8 | 532 + FE_CAN_FEC_AUTO | 533 + FE_CAN_QPSK | 534 + FE_CAN_QAM_16 | 535 + FE_CAN_QAM_64 | 536 + FE_CAN_QAM_AUTO | 537 + FE_CAN_TRANSMISSION_MODE_AUTO | 538 + FE_CAN_GUARD_INTERVAL_AUTO | 539 + FE_CAN_HIERARCHY_AUTO | 540 + FE_CAN_RECOVER | 541 + FE_CAN_MUTE_TS 542 + }, 543 + 544 + .release = rtl2830_release, 545 + 546 + .init = rtl2830_init, 547 + .sleep = rtl2830_sleep, 548 + 549 + .get_tune_settings = rtl2830_get_tune_settings, 550 + 551 + .set_frontend = rtl2830_set_frontend, 552 + 553 + .read_status = rtl2830_read_status, 554 + .read_snr = rtl2830_read_snr, 555 + .read_ber = rtl2830_read_ber, 556 + .read_ucblocks = rtl2830_read_ucblocks, 557 + .read_signal_strength = rtl2830_read_signal_strength, 558 + }; 559 + 560 + MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 561 + MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver"); 562 + MODULE_LICENSE("GPL");
+97
drivers/media/dvb/frontends/rtl2830.h
··· 1 + /* 2 + * Realtek RTL2830 DVB-T demodulator driver 3 + * 4 + * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> 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 as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along 17 + * with this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 + */ 20 + 21 + #ifndef RTL2830_H 22 + #define RTL2830_H 23 + 24 + #include <linux/dvb/frontend.h> 25 + 26 + struct rtl2830_config { 27 + /* 28 + * Demodulator I2C address. 29 + */ 30 + u8 i2c_addr; 31 + 32 + /* 33 + * Xtal frequency. 34 + * Hz 35 + * 4000000, 16000000, 25000000, 28800000 36 + */ 37 + u32 xtal; 38 + 39 + /* 40 + * TS output mode. 41 + */ 42 + u8 ts_mode; 43 + 44 + /* 45 + * Spectrum inversion. 46 + */ 47 + bool spec_inv; 48 + 49 + /* 50 + * IFs for all used modes. 51 + * Hz 52 + * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000 53 + */ 54 + u32 if_dvbt; 55 + 56 + /* 57 + */ 58 + u8 vtop; 59 + 60 + /* 61 + */ 62 + u8 krf; 63 + 64 + /* 65 + */ 66 + u8 agc_targ_val; 67 + }; 68 + 69 + #if defined(CONFIG_DVB_RTL2830) || \ 70 + (defined(CONFIG_DVB_RTL2830_MODULE) && defined(MODULE)) 71 + extern struct dvb_frontend *rtl2830_attach( 72 + const struct rtl2830_config *config, 73 + struct i2c_adapter *i2c 74 + ); 75 + 76 + extern struct i2c_adapter *rtl2830_get_tuner_i2c_adapter( 77 + struct dvb_frontend *fe 78 + ); 79 + #else 80 + static inline struct dvb_frontend *rtl2830_attach( 81 + const struct rtl2830_config *config, 82 + struct i2c_adapter *i2c 83 + ) 84 + { 85 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 86 + return NULL; 87 + } 88 + 89 + static inline struct i2c_adapter *rtl2830_get_tuner_i2c_adapter( 90 + struct dvb_frontend *fe 91 + ) 92 + { 93 + return NULL; 94 + } 95 + #endif 96 + 97 + #endif /* RTL2830_H */
+57
drivers/media/dvb/frontends/rtl2830_priv.h
··· 1 + /* 2 + * Realtek RTL2830 DVB-T demodulator driver 3 + * 4 + * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> 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 as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along 17 + * with this program; if not, write to the Free Software Foundation, Inc., 18 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 + */ 20 + 21 + #ifndef RTL2830_PRIV_H 22 + #define RTL2830_PRIV_H 23 + 24 + #include "dvb_frontend.h" 25 + #include "rtl2830.h" 26 + 27 + #define LOG_PREFIX "rtl2830" 28 + 29 + #undef dbg 30 + #define dbg(f, arg...) \ 31 + if (rtl2830_debug) \ 32 + printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) 33 + #undef err 34 + #define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) 35 + #undef info 36 + #define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) 37 + #undef warn 38 + #define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) 39 + 40 + struct rtl2830_priv { 41 + struct i2c_adapter *i2c; 42 + struct dvb_frontend fe; 43 + struct rtl2830_config cfg; 44 + struct i2c_adapter tuner_i2c_adapter; 45 + 46 + bool sleeping; 47 + 48 + u8 page; /* active register page */ 49 + }; 50 + 51 + struct rtl2830_reg_val_mask { 52 + u16 reg; 53 + u8 val; 54 + u8 mask; 55 + }; 56 + 57 + #endif /* RTL2830_PRIV_H */
+7 -5
drivers/media/dvb/frontends/stb0899_drv.c
··· 67 67 * Crude linear extrapolation below -84.8dBm and above -8.0dBm. 68 68 */ 69 69 static const struct stb0899_tab stb0899_dvbsrf_tab[] = { 70 - { -950, -128 }, 70 + { -750, -128 }, 71 71 { -748, -94 }, 72 72 { -745, -92 }, 73 73 { -735, -90 }, ··· 131 131 { -730, 13645 }, 132 132 { -750, 13909 }, 133 133 { -766, 14153 }, 134 - { -999, 16383 } 134 + { -950, 16383 } 135 135 }; 136 136 137 137 /* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/ ··· 964 964 965 965 int val; 966 966 u32 reg; 967 + *strength = 0; 967 968 switch (state->delsys) { 968 969 case SYS_DVBS: 969 970 case SYS_DSS: ··· 984 983 break; 985 984 case SYS_DVBS2: 986 985 if (internal->lock) { 987 - reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN); 986 + reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_GAIN); 988 987 val = STB0899_GETFIELD(IF_AGC_GAIN, reg); 989 988 990 989 *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val); 991 - *strength += 750; 990 + *strength += 950; 992 991 dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm", 993 992 val & 0x3fff, *strength); 994 993 } ··· 1010 1009 u8 buf[2]; 1011 1010 u32 reg; 1012 1011 1012 + *snr = 0; 1013 1013 reg = stb0899_read_reg(state, STB0899_VSTATUS); 1014 1014 switch (state->delsys) { 1015 1015 case SYS_DVBS: ··· 1073 1071 reg = stb0899_read_reg(state, STB0899_VSTATUS); 1074 1072 if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { 1075 1073 dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK"); 1076 - *status |= FE_HAS_CARRIER | FE_HAS_LOCK; 1074 + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK; 1077 1075 1078 1076 reg = stb0899_read_reg(state, STB0899_PLPARM); 1079 1077 if (STB0899_GETFIELD(VITCURPUN, reg)) {
+1 -1
drivers/media/dvb/frontends/stv0288.c
··· 506 506 tda[1] = (unsigned char)tm; 507 507 stv0288_writeregI(state, 0x2b, tda[1]); 508 508 stv0288_writeregI(state, 0x2c, tda[2]); 509 - udelay(30); 509 + msleep(30); 510 510 } 511 511 state->tuner_frequency = c->frequency; 512 512 state->fec_inner = FEC_AUTO;
+1 -1
drivers/media/dvb/frontends/tda10071.c
··· 1215 1215 EXPORT_SYMBOL(tda10071_attach); 1216 1216 1217 1217 static struct dvb_frontend_ops tda10071_ops = { 1218 - .delsys = { SYS_DVBT, SYS_DVBT2 }, 1218 + .delsys = { SYS_DVBS, SYS_DVBS2 }, 1219 1219 .info = { 1220 1220 .name = "NXP TDA10071", 1221 1221 .frequency_min = 950000,
+1
drivers/media/dvb/ngene/ngene-cards.c
··· 216 216 struct drxk_config config; 217 217 218 218 memset(&config, 0, sizeof(config)); 219 + config.microcode_name = "drxk_a3.mc"; 219 220 config.adr = 0x29 + (chan->number ^ 2); 220 221 221 222 chan->fe = dvb_attach(drxk_attach, &config, i2c);
+65 -28
drivers/media/dvb/pt1/pt1.c
··· 28 28 #include <linux/pci.h> 29 29 #include <linux/kthread.h> 30 30 #include <linux/freezer.h> 31 + #include <linux/ratelimit.h> 31 32 32 33 #include "dvbdev.h" 33 34 #include "dvb_demux.h" ··· 78 77 struct pt1_adapter *adaps[PT1_NR_ADAPS]; 79 78 struct pt1_table *tables; 80 79 struct task_struct *kthread; 80 + int table_index; 81 + int buf_index; 81 82 82 83 struct mutex lock; 83 84 int power; ··· 93 90 u8 *buf; 94 91 int upacket_count; 95 92 int packet_count; 93 + int st_count; 96 94 97 95 struct dvb_adapter adap; 98 96 struct dvb_demux demux; 99 97 int users; 100 98 struct dmxdev dmxdev; 101 - struct dvb_net net; 102 99 struct dvb_frontend *fe; 103 100 int (*orig_set_voltage)(struct dvb_frontend *fe, 104 101 fe_sec_voltage_t voltage); ··· 122 119 return readl(pt1->regs + reg * 4); 123 120 } 124 121 125 - static int pt1_nr_tables = 64; 122 + static int pt1_nr_tables = 8; 126 123 module_param_named(nr_tables, pt1_nr_tables, int, 0); 127 124 128 125 static void pt1_increment_table_count(struct pt1 *pt1) ··· 267 264 struct pt1_adapter *adap; 268 265 int offset; 269 266 u8 *buf; 267 + int sc; 270 268 271 269 if (!page->upackets[PT1_NR_UPACKETS - 1]) 272 270 return 0; ··· 283 279 adap->upacket_count = 0; 284 280 else if (!adap->upacket_count) 285 281 continue; 282 + 283 + if (upacket >> 24 & 1) 284 + printk_ratelimited(KERN_INFO "earth-pt1: device " 285 + "buffer overflowing. table[%d] buf[%d]\n", 286 + pt1->table_index, pt1->buf_index); 287 + sc = upacket >> 26 & 0x7; 288 + if (adap->st_count != -1 && sc != ((adap->st_count + 1) & 0x7)) 289 + printk_ratelimited(KERN_INFO "earth-pt1: data loss" 290 + " in streamID(adapter)[%d]\n", index); 291 + adap->st_count = sc; 286 292 287 293 buf = adap->buf; 288 294 offset = adap->packet_count * 188 + adap->upacket_count * 3; ··· 317 303 static int pt1_thread(void *data) 318 304 { 319 305 struct pt1 *pt1; 320 - int table_index; 321 - int buf_index; 322 306 struct pt1_buffer_page *page; 323 307 324 308 pt1 = data; 325 309 set_freezable(); 326 310 327 - table_index = 0; 328 - buf_index = 0; 329 - 330 311 while (!kthread_should_stop()) { 331 312 try_to_freeze(); 332 313 333 - page = pt1->tables[table_index].bufs[buf_index].page; 314 + page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page; 334 315 if (!pt1_filter(pt1, page)) { 335 316 schedule_timeout_interruptible((HZ + 999) / 1000); 336 317 continue; 337 318 } 338 319 339 - if (++buf_index >= PT1_NR_BUFS) { 320 + if (++pt1->buf_index >= PT1_NR_BUFS) { 340 321 pt1_increment_table_count(pt1); 341 - buf_index = 0; 342 - if (++table_index >= pt1_nr_tables) 343 - table_index = 0; 322 + pt1->buf_index = 0; 323 + if (++pt1->table_index >= pt1_nr_tables) 324 + pt1->table_index = 0; 344 325 } 345 326 } 346 327 ··· 486 477 return ret; 487 478 } 488 479 480 + static int pt1_start_polling(struct pt1 *pt1) 481 + { 482 + int ret = 0; 483 + 484 + mutex_lock(&pt1->lock); 485 + if (!pt1->kthread) { 486 + pt1->kthread = kthread_run(pt1_thread, pt1, "earth-pt1"); 487 + if (IS_ERR(pt1->kthread)) { 488 + ret = PTR_ERR(pt1->kthread); 489 + pt1->kthread = NULL; 490 + } 491 + } 492 + mutex_unlock(&pt1->lock); 493 + return ret; 494 + } 495 + 489 496 static int pt1_start_feed(struct dvb_demux_feed *feed) 490 497 { 491 498 struct pt1_adapter *adap; 492 499 adap = container_of(feed->demux, struct pt1_adapter, demux); 493 - if (!adap->users++) 500 + if (!adap->users++) { 501 + int ret; 502 + 503 + ret = pt1_start_polling(adap->pt1); 504 + if (ret) 505 + return ret; 494 506 pt1_set_stream(adap->pt1, adap->index, 1); 507 + } 495 508 return 0; 509 + } 510 + 511 + static void pt1_stop_polling(struct pt1 *pt1) 512 + { 513 + int i, count; 514 + 515 + mutex_lock(&pt1->lock); 516 + for (i = 0, count = 0; i < PT1_NR_ADAPS; i++) 517 + count += pt1->adaps[i]->users; 518 + 519 + if (count == 0 && pt1->kthread) { 520 + kthread_stop(pt1->kthread); 521 + pt1->kthread = NULL; 522 + } 523 + mutex_unlock(&pt1->lock); 496 524 } 497 525 498 526 static int pt1_stop_feed(struct dvb_demux_feed *feed) 499 527 { 500 528 struct pt1_adapter *adap; 501 529 adap = container_of(feed->demux, struct pt1_adapter, demux); 502 - if (!--adap->users) 530 + if (!--adap->users) { 503 531 pt1_set_stream(adap->pt1, adap->index, 0); 532 + pt1_stop_polling(adap->pt1); 533 + } 504 534 return 0; 505 535 } 506 536 ··· 623 575 624 576 static void pt1_free_adapter(struct pt1_adapter *adap) 625 577 { 626 - dvb_net_release(&adap->net); 627 578 adap->demux.dmx.close(&adap->demux.dmx); 628 579 dvb_dmxdev_release(&adap->dmxdev); 629 580 dvb_dmx_release(&adap->demux); ··· 663 616 adap->buf = buf; 664 617 adap->upacket_count = 0; 665 618 adap->packet_count = 0; 619 + adap->st_count = -1; 666 620 667 621 dvb_adap = &adap->adap; 668 622 dvb_adap->priv = adap; ··· 691 643 ret = dvb_dmxdev_init(dmxdev, dvb_adap); 692 644 if (ret < 0) 693 645 goto err_dmx_release; 694 - 695 - dvb_net_init(dvb_adap, &adap->net, &demux->dmx); 696 646 697 647 return adap; 698 648 ··· 1066 1020 pt1 = pci_get_drvdata(pdev); 1067 1021 regs = pt1->regs; 1068 1022 1069 - kthread_stop(pt1->kthread); 1023 + if (pt1->kthread) 1024 + kthread_stop(pt1->kthread); 1070 1025 pt1_cleanup_tables(pt1); 1071 1026 pt1_cleanup_frontends(pt1); 1072 1027 pt1_disable_ram(pt1); ··· 1090 1043 void __iomem *regs; 1091 1044 struct pt1 *pt1; 1092 1045 struct i2c_adapter *i2c_adap; 1093 - struct task_struct *kthread; 1094 1046 1095 1047 ret = pci_enable_device(pdev); 1096 1048 if (ret < 0) ··· 1185 1139 if (ret < 0) 1186 1140 goto err_pt1_cleanup_frontends; 1187 1141 1188 - kthread = kthread_run(pt1_thread, pt1, "pt1"); 1189 - if (IS_ERR(kthread)) { 1190 - ret = PTR_ERR(kthread); 1191 - goto err_pt1_cleanup_tables; 1192 - } 1193 - 1194 - pt1->kthread = kthread; 1195 1142 return 0; 1196 1143 1197 - err_pt1_cleanup_tables: 1198 - pt1_cleanup_tables(pt1); 1199 1144 err_pt1_cleanup_frontends: 1200 1145 pt1_cleanup_frontends(pt1); 1201 1146 err_pt1_disable_ram:
+1 -1
drivers/media/media-devnode.c
··· 312 312 unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES); 313 313 } 314 314 315 - module_init(media_devnode_init) 315 + subsys_initcall(media_devnode_init); 316 316 module_exit(media_devnode_exit) 317 317 318 318 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+49 -76
drivers/media/radio/Kconfig
··· 43 43 44 44 config RADIO_MAXIRADIO 45 45 tristate "Guillemot MAXI Radio FM 2000 radio" 46 - depends on VIDEO_V4L2 && PCI 46 + depends on VIDEO_V4L2 && PCI && SND 47 47 ---help--- 48 48 Choose Y here if you have this radio card. This card may also be 49 49 found as Gemtek PCI FM. ··· 79 79 80 80 To compile this driver as a module, choose M here: the 81 81 module will be called radio-si4713. 82 + 83 + config USB_KEENE 84 + tristate "Keene FM Transmitter USB support" 85 + depends on USB && VIDEO_V4L2 86 + ---help--- 87 + Say Y here if you want to connect this type of FM transmitter 88 + to your computer's USB port. 89 + 90 + To compile this driver as a module, choose M here: the 91 + module will be called radio-keene. 82 92 83 93 config RADIO_TEA5764 84 94 tristate "TEA5764 I2C FM radio support" ··· 177 167 178 168 if V4L_RADIO_ISA_DRIVERS 179 169 170 + config RADIO_ISA 171 + depends on ISA 172 + tristate 173 + 180 174 config RADIO_CADET 181 175 tristate "ADS Cadet AM/FM Tuner" 182 176 depends on ISA && VIDEO_V4L2 ··· 188 174 Choose Y here if you have one of these AM/FM radio cards, and then 189 175 fill in the port address below. 190 176 191 - In order to control your radio card, you will need to use programs 192 - that are compatible with the Video For Linux API. Information on 193 - this API and pointers to "v4l" programs may be found at 194 - <file:Documentation/video4linux/API.html>. 195 - 196 - Further documentation on this driver can be found on the WWW at 197 - <http://linux.blackhawke.net/cadet/>. 198 - 199 177 To compile this driver as a module, choose M here: the 200 178 module will be called radio-cadet. 201 179 202 180 config RADIO_RTRACK 203 181 tristate "AIMSlab RadioTrack (aka RadioReveal) support" 204 182 depends on ISA && VIDEO_V4L2 183 + select RADIO_ISA 205 184 ---help--- 206 185 Choose Y here if you have one of these FM radio cards, and then fill 207 186 in the port address below. ··· 208 201 You must also pass the module a suitable io parameter, 0x248 has 209 202 been reported to be used by these cards. 210 203 211 - In order to control your radio card, you will need to use programs 212 - that are compatible with the Video For Linux API. Information on 213 - this API and pointers to "v4l" programs may be found at 214 - <file:Documentation/video4linux/API.html>. More information is 215 - contained in the file 204 + More information is contained in the file 216 205 <file:Documentation/video4linux/radiotrack.txt>. 217 206 218 207 To compile this driver as a module, choose M here: the ··· 217 214 config RADIO_RTRACK_PORT 218 215 hex "RadioTrack i/o port (0x20f or 0x30f)" 219 216 depends on RADIO_RTRACK=y 220 - default "20f" 217 + default "30f" 221 218 help 222 219 Enter either 0x30f or 0x20f here. The card default is 0x30f, if you 223 220 haven't changed the jumper setting on the card. ··· 225 222 config RADIO_RTRACK2 226 223 tristate "AIMSlab RadioTrack II support" 227 224 depends on ISA && VIDEO_V4L2 225 + select RADIO_ISA 228 226 ---help--- 229 227 Choose Y here if you have this FM radio card, and then fill in the 230 228 port address below. 231 229 232 - In order to control your radio card, you will need to use programs 233 - that are compatible with the Video For Linux API. Information on 234 - this API and pointers to "v4l" programs may be found at 235 - <file:Documentation/video4linux/API.html>. 230 + Note: this driver hasn't been tested since a long time due to lack 231 + of hardware. If you have this hardware, then please contact the 232 + linux-media mailinglist. 236 233 237 234 To compile this driver as a module, choose M here: the 238 235 module will be called radio-rtrack2. ··· 248 245 config RADIO_AZTECH 249 246 tristate "Aztech/Packard Bell Radio" 250 247 depends on ISA && VIDEO_V4L2 248 + select RADIO_ISA 251 249 ---help--- 252 250 Choose Y here if you have one of these FM radio cards, and then fill 253 251 in the port address below. 254 - 255 - In order to control your radio card, you will need to use programs 256 - that are compatible with the Video For Linux API. Information on 257 - this API and pointers to "v4l" programs may be found at 258 - <file:Documentation/video4linux/API.html>. 259 252 260 253 To compile this driver as a module, choose M here: the 261 254 module will be called radio-aztech. ··· 268 269 config RADIO_GEMTEK 269 270 tristate "GemTek Radio card (or compatible) support" 270 271 depends on ISA && VIDEO_V4L2 272 + select RADIO_ISA 271 273 ---help--- 272 274 Choose Y here if you have this FM radio card, and then fill in the 273 275 I/O port address and settings below. The following cards either have ··· 278 278 - Typhoon Radio card (some models) 279 279 - Hama Radio card 280 280 281 - In order to control your radio card, you will need to use programs 282 - that are compatible with the Video For Linux API. Information on 283 - this API and pointers to "v4l" programs may be found at 284 - <file:Documentation/video4linux/API.html>. 285 - 286 281 To compile this driver as a module, choose M here: the 287 282 module will be called radio-gemtek. 288 283 289 284 config RADIO_GEMTEK_PORT 290 - hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0c24c or 0x28c)" 285 + hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0x248 or 0x28c)" 291 286 depends on RADIO_GEMTEK=y 292 287 default "34c" 293 288 help 294 - Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is 295 - 0x34c, if you haven't changed the jumper setting on the card. On 296 - Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O 289 + Enter either 0x20c, 0x30c, 0x24c, 0x34c, 0x248 or 0x28c here. The 290 + card default is 0x34c, if you haven't changed the jumper setting 291 + on the card. 292 + 293 + On Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O 297 294 port is 0x20c, 0x248 or 0x28c. 295 + 298 296 If automatic I/O port probing is enabled this port will be used only 299 297 in case of automatic probing failure, ie. as a fallback. 300 298 ··· 316 318 sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this 317 319 is required for the radio-miropcm20. 318 320 319 - In order to control your radio card, you will need to use programs 320 - that are compatible with the Video For Linux API. Information on 321 - this API and pointers to "v4l" programs may be found at 322 - <file:Documentation/video4linux/API.html>. 323 - 324 321 To compile this driver as a module, choose M here: the 325 322 module will be called radio-miropcm20. 326 323 ··· 324 331 depends on ISA && VIDEO_V4L2 325 332 ---help--- 326 333 Choose Y here if you have one of these FM radio cards. 327 - 328 - In order to control your radio card, you will need to use programs 329 - that are compatible with the Video For Linux API. Information on 330 - this API and pointers to "v4l" programs may be found at 331 - <file:Documentation/video4linux/API.html>. 332 334 333 335 To compile this driver as a module, choose M here: the 334 336 module will be called radio-sf16fmi. ··· 334 346 ---help--- 335 347 Choose Y here if you have one of these FM radio cards. 336 348 337 - In order to control your radio card, you will need to use programs 338 - that are compatible with the Video For Linux API. Information on 339 - this API and pointers to "v4l" programs may be found on the WWW at 340 - <http://roadrunner.swansea.uk.linux.org/v4l.shtml>. 341 - 342 349 To compile this driver as a module, choose M here: the 343 350 module will be called radio-sf16fmr2. 344 351 345 352 config RADIO_TERRATEC 346 353 tristate "TerraTec ActiveRadio ISA Standalone" 347 354 depends on ISA && VIDEO_V4L2 355 + select RADIO_ISA 348 356 ---help--- 349 - Choose Y here if you have this FM radio card, and then fill in the 350 - port address below. (TODO) 357 + Choose Y here if you have this FM radio card. 351 358 352 - Note: This driver is in its early stages. Right now volume and 353 - frequency control and muting works at least for me, but 354 - unfortunately I have not found anybody who wants to use this card 355 - with Linux. So if it is this what YOU are trying to do right now, 356 - PLEASE DROP ME A NOTE!! Rolf Offermanns <rolf@offermanns.de>. 357 - 358 - In order to control your radio card, you will need to use programs 359 - that are compatible with the Video For Linux API. Information on 360 - this API and pointers to "v4l" programs may be found at 361 - <file:Documentation/video4linux/API.html>. 359 + Note: this driver hasn't been tested since a long time due to lack 360 + of hardware. If you have this hardware, then please contact the 361 + linux-media mailinglist. 362 362 363 363 To compile this driver as a module, choose M here: the 364 364 module will be called radio-terratec. 365 365 366 - config RADIO_TERRATEC_PORT 367 - hex "Terratec i/o port (normally 0x590)" 368 - depends on RADIO_TERRATEC=y 369 - default "590" 370 - help 371 - Fill in the I/O port of your TerraTec FM radio card. If unsure, go 372 - with the default. 373 - 374 366 config RADIO_TRUST 375 367 tristate "Trust FM radio card" 376 368 depends on ISA && VIDEO_V4L2 369 + select RADIO_ISA 377 370 help 378 371 This is a driver for the Trust FM radio cards. Say Y if you have 379 372 such a card and want to use it under Linux. 373 + 374 + Note: this driver hasn't been tested since a long time due to lack 375 + of hardware. If you have this hardware, then please contact the 376 + linux-media mailinglist. 380 377 381 378 To compile this driver as a module, choose M here: the 382 379 module will be called radio-trust. ··· 377 404 config RADIO_TYPHOON 378 405 tristate "Typhoon Radio (a.k.a. EcoRadio)" 379 406 depends on ISA && VIDEO_V4L2 407 + select RADIO_ISA 380 408 ---help--- 381 409 Choose Y here if you have one of these FM radio cards, and then fill 382 410 in the port address and the frequency used for muting below. 383 411 384 - In order to control your radio card, you will need to use programs 385 - that are compatible with the Video For Linux API. Information on 386 - this API and pointers to "v4l" programs may be found at 387 - <file:Documentation/video4linux/API.html>. 412 + Note: this driver hasn't been tested since a long time due to lack 413 + of hardware. If you have this hardware, then please contact the 414 + linux-media mailinglist. 388 415 389 416 To compile this driver as a module, choose M here: the 390 417 module will be called radio-typhoon. ··· 411 438 config RADIO_ZOLTRIX 412 439 tristate "Zoltrix Radio" 413 440 depends on ISA && VIDEO_V4L2 441 + select RADIO_ISA 414 442 ---help--- 415 443 Choose Y here if you have one of these FM radio cards, and then fill 416 444 in the port address below. 417 445 418 - In order to control your radio card, you will need to use programs 419 - that are compatible with the Video For Linux API. Information on 420 - this API and pointers to "v4l" programs may be found at 421 - <file:Documentation/video4linux/API.html>. 446 + Note: this driver hasn't been tested since a long time due to lack 447 + of hardware. If you have this hardware, then please contact the 448 + linux-media mailinglist. 422 449 423 450 To compile this driver as a module, choose M here: the 424 451 module will be called radio-zoltrix.
+2
drivers/media/radio/Makefile
··· 2 2 # Makefile for the kernel character device drivers. 3 3 # 4 4 5 + obj-$(CONFIG_RADIO_ISA) += radio-isa.o 5 6 obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o 6 7 obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o 7 8 obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o ··· 21 20 obj-$(CONFIG_USB_DSBR) += dsbr100.o 22 21 obj-$(CONFIG_RADIO_SI470X) += si470x/ 23 22 obj-$(CONFIG_USB_MR800) += radio-mr800.o 23 + obj-$(CONFIG_USB_KEENE) += radio-keene.o 24 24 obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o 25 25 obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o 26 26 obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
+109 -333
drivers/media/radio/radio-aimslab.c
··· 1 - /* radiotrack (radioreveal) driver for Linux radio support 2 - * (c) 1997 M. Kirkwood 1 + /* 2 + * AimsLab RadioTrack (aka RadioVeveal) driver 3 + * 4 + * Copyright 1997 M. Kirkwood 5 + * 6 + * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> 3 7 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 4 8 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> 5 9 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 6 - * 7 - * History: 8 - * 1999-02-24 Russell Kroll <rkroll@exploits.org> 9 - * Fine tuning/VIDEO_TUNER_LOW 10 - * Frequency range expanded to start at 87 MHz 11 - * 12 - * TODO: Allow for more than one of these foolish entities :-) 13 10 * 14 11 * Notes on the hardware (reverse engineered from other peoples' 15 12 * reverse engineering of AIMS' code :-) ··· 23 26 * wait(a_wee_while); 24 27 * out(port, stop_changing_the_volume); 25 28 * 29 + * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool. 26 30 */ 27 31 28 32 #include <linux/module.h> /* Modules */ ··· 32 34 #include <linux/delay.h> /* msleep */ 33 35 #include <linux/videodev2.h> /* kernel radio structs */ 34 36 #include <linux/io.h> /* outb, outb_p */ 37 + #include <linux/slab.h> 35 38 #include <media/v4l2-device.h> 36 39 #include <media/v4l2-ioctl.h> 40 + #include <media/v4l2-ctrls.h> 41 + #include "radio-isa.h" 37 42 38 - MODULE_AUTHOR("M.Kirkwood"); 43 + MODULE_AUTHOR("M. Kirkwood"); 39 44 MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card."); 40 45 MODULE_LICENSE("GPL"); 41 - MODULE_VERSION("0.0.3"); 46 + MODULE_VERSION("1.0.0"); 42 47 43 48 #ifndef CONFIG_RADIO_RTRACK_PORT 44 49 #define CONFIG_RADIO_RTRACK_PORT -1 45 50 #endif 46 51 47 - static int io = CONFIG_RADIO_RTRACK_PORT; 48 - static int radio_nr = -1; 52 + #define RTRACK_MAX 2 49 53 50 - module_param(io, int, 0); 51 - MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)"); 52 - module_param(radio_nr, int, 0); 54 + static int io[RTRACK_MAX] = { [0] = CONFIG_RADIO_RTRACK_PORT, 55 + [1 ... (RTRACK_MAX - 1)] = -1 }; 56 + static int radio_nr[RTRACK_MAX] = { [0 ... (RTRACK_MAX - 1)] = -1 }; 53 57 54 - struct rtrack 55 - { 56 - struct v4l2_device v4l2_dev; 57 - struct video_device vdev; 58 - int port; 58 + module_param_array(io, int, NULL, 0444); 59 + MODULE_PARM_DESC(io, "I/O addresses of the RadioTrack card (0x20f or 0x30f)"); 60 + module_param_array(radio_nr, int, NULL, 0444); 61 + MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 62 + 63 + struct rtrack { 64 + struct radio_isa_card isa; 59 65 int curvol; 60 - unsigned long curfreq; 61 - int muted; 62 - int io; 63 - struct mutex lock; 64 66 }; 65 67 66 - static struct rtrack rtrack_card; 67 - 68 - /* local things */ 69 - 70 - static void rt_decvol(struct rtrack *rt) 68 + static struct radio_isa_card *rtrack_alloc(void) 71 69 { 72 - outb(0x58, rt->io); /* volume down + sigstr + on */ 73 - msleep(100); 74 - outb(0xd8, rt->io); /* volume steady + sigstr + on */ 70 + struct rtrack *rt = kzalloc(sizeof(struct rtrack), GFP_KERNEL); 71 + 72 + if (rt) 73 + rt->curvol = 0xff; 74 + return rt ? &rt->isa : NULL; 75 75 } 76 76 77 - static void rt_incvol(struct rtrack *rt) 78 - { 79 - outb(0x98, rt->io); /* volume up + sigstr + on */ 80 - msleep(100); 81 - outb(0xd8, rt->io); /* volume steady + sigstr + on */ 82 - } 83 - 84 - static void rt_mute(struct rtrack *rt) 85 - { 86 - rt->muted = 1; 87 - mutex_lock(&rt->lock); 88 - outb(0xd0, rt->io); /* volume steady, off */ 89 - mutex_unlock(&rt->lock); 90 - } 91 - 92 - static int rt_setvol(struct rtrack *rt, int vol) 93 - { 94 - int i; 95 - 96 - mutex_lock(&rt->lock); 97 - 98 - if (vol == rt->curvol) { /* requested volume = current */ 99 - if (rt->muted) { /* user is unmuting the card */ 100 - rt->muted = 0; 101 - outb(0xd8, rt->io); /* enable card */ 102 - } 103 - mutex_unlock(&rt->lock); 104 - return 0; 105 - } 106 - 107 - if (vol == 0) { /* volume = 0 means mute the card */ 108 - outb(0x48, rt->io); /* volume down but still "on" */ 109 - msleep(2000); /* make sure it's totally down */ 110 - outb(0xd0, rt->io); /* volume steady, off */ 111 - rt->curvol = 0; /* track the volume state! */ 112 - mutex_unlock(&rt->lock); 113 - return 0; 114 - } 115 - 116 - rt->muted = 0; 117 - if (vol > rt->curvol) 118 - for (i = rt->curvol; i < vol; i++) 119 - rt_incvol(rt); 120 - else 121 - for (i = rt->curvol; i > vol; i--) 122 - rt_decvol(rt); 123 - 124 - rt->curvol = vol; 125 - mutex_unlock(&rt->lock); 126 - return 0; 127 - } 128 - 129 - /* the 128+64 on these outb's is to keep the volume stable while tuning 130 - * without them, the volume _will_ creep up with each frequency change 131 - * and bit 4 (+16) is to keep the signal strength meter enabled 77 + /* The 128+64 on these outb's is to keep the volume stable while tuning. 78 + * Without them, the volume _will_ creep up with each frequency change 79 + * and bit 4 (+16) is to keep the signal strength meter enabled. 132 80 */ 133 81 134 - static void send_0_byte(struct rtrack *rt) 82 + static void send_0_byte(struct radio_isa_card *isa, int on) 135 83 { 136 - if (rt->curvol == 0 || rt->muted) { 137 - outb_p(128+64+16+ 1, rt->io); /* wr-enable + data low */ 138 - outb_p(128+64+16+2+1, rt->io); /* clock */ 139 - } 140 - else { 141 - outb_p(128+64+16+8+ 1, rt->io); /* on + wr-enable + data low */ 142 - outb_p(128+64+16+8+2+1, rt->io); /* clock */ 143 - } 84 + outb_p(128+64+16+on+1, isa->io); /* wr-enable + data low */ 85 + outb_p(128+64+16+on+2+1, isa->io); /* clock */ 144 86 msleep(1); 145 87 } 146 88 147 - static void send_1_byte(struct rtrack *rt) 89 + static void send_1_byte(struct radio_isa_card *isa, int on) 148 90 { 149 - if (rt->curvol == 0 || rt->muted) { 150 - outb_p(128+64+16+4 +1, rt->io); /* wr-enable+data high */ 151 - outb_p(128+64+16+4+2+1, rt->io); /* clock */ 152 - } 153 - else { 154 - outb_p(128+64+16+8+4 +1, rt->io); /* on+wr-enable+data high */ 155 - outb_p(128+64+16+8+4+2+1, rt->io); /* clock */ 156 - } 157 - 91 + outb_p(128+64+16+on+4+1, isa->io); /* wr-enable+data high */ 92 + outb_p(128+64+16+on+4+2+1, isa->io); /* clock */ 158 93 msleep(1); 159 94 } 160 95 161 - static int rt_setfreq(struct rtrack *rt, unsigned long freq) 96 + static int rtrack_s_frequency(struct radio_isa_card *isa, u32 freq) 162 97 { 98 + int on = v4l2_ctrl_g_ctrl(isa->mute) ? 0 : 8; 163 99 int i; 164 - 165 - mutex_lock(&rt->lock); /* Stop other ops interfering */ 166 - 167 - rt->curfreq = freq; 168 - 169 - /* now uses VIDEO_TUNER_LOW for fine tuning */ 170 100 171 101 freq += 171200; /* Add 10.7 MHz IF */ 172 102 freq /= 800; /* Convert to 50 kHz units */ 173 103 174 - send_0_byte(rt); /* 0: LSB of frequency */ 104 + send_0_byte(isa, on); /* 0: LSB of frequency */ 175 105 176 106 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ 177 107 if (freq & (1 << i)) 178 - send_1_byte(rt); 108 + send_1_byte(isa, on); 179 109 else 180 - send_0_byte(rt); 110 + send_0_byte(isa, on); 181 111 182 - send_0_byte(rt); /* 14: test bit - always 0 */ 183 - send_0_byte(rt); /* 15: test bit - always 0 */ 112 + send_0_byte(isa, on); /* 14: test bit - always 0 */ 113 + send_0_byte(isa, on); /* 15: test bit - always 0 */ 184 114 185 - send_0_byte(rt); /* 16: band data 0 - always 0 */ 186 - send_0_byte(rt); /* 17: band data 1 - always 0 */ 187 - send_0_byte(rt); /* 18: band data 2 - always 0 */ 188 - send_0_byte(rt); /* 19: time base - always 0 */ 115 + send_0_byte(isa, on); /* 16: band data 0 - always 0 */ 116 + send_0_byte(isa, on); /* 17: band data 1 - always 0 */ 117 + send_0_byte(isa, on); /* 18: band data 2 - always 0 */ 118 + send_0_byte(isa, on); /* 19: time base - always 0 */ 189 119 190 - send_0_byte(rt); /* 20: spacing (0 = 25 kHz) */ 191 - send_1_byte(rt); /* 21: spacing (1 = 25 kHz) */ 192 - send_0_byte(rt); /* 22: spacing (0 = 25 kHz) */ 193 - send_1_byte(rt); /* 23: AM/FM (FM = 1, always) */ 120 + send_0_byte(isa, on); /* 20: spacing (0 = 25 kHz) */ 121 + send_1_byte(isa, on); /* 21: spacing (1 = 25 kHz) */ 122 + send_0_byte(isa, on); /* 22: spacing (0 = 25 kHz) */ 123 + send_1_byte(isa, on); /* 23: AM/FM (FM = 1, always) */ 194 124 195 - if (rt->curvol == 0 || rt->muted) 196 - outb(0xd0, rt->io); /* volume steady + sigstr */ 197 - else 198 - outb(0xd8, rt->io); /* volume steady + sigstr + on */ 199 - 200 - mutex_unlock(&rt->lock); 201 - 125 + outb(0xd0 + on, isa->io); /* volume steady + sigstr */ 202 126 return 0; 203 127 } 204 128 205 - static int rt_getsigstr(struct rtrack *rt) 129 + static u32 rtrack_g_signal(struct radio_isa_card *isa) 206 130 { 207 - int sig = 1; 208 - 209 - mutex_lock(&rt->lock); 210 - if (inb(rt->io) & 2) /* bit set = no signal present */ 211 - sig = 0; 212 - mutex_unlock(&rt->lock); 213 - return sig; 131 + /* bit set = no signal present */ 132 + return 0xffff * !(inb(isa->io) & 2); 214 133 } 215 134 216 - static int vidioc_querycap(struct file *file, void *priv, 217 - struct v4l2_capability *v) 135 + static int rtrack_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) 218 136 { 219 - strlcpy(v->driver, "radio-aimslab", sizeof(v->driver)); 220 - strlcpy(v->card, "RadioTrack", sizeof(v->card)); 221 - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 222 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 223 - return 0; 224 - } 137 + struct rtrack *rt = container_of(isa, struct rtrack, isa); 138 + int curvol = rt->curvol; 225 139 226 - static int vidioc_g_tuner(struct file *file, void *priv, 227 - struct v4l2_tuner *v) 228 - { 229 - struct rtrack *rt = video_drvdata(file); 230 - 231 - if (v->index > 0) 232 - return -EINVAL; 233 - 234 - strlcpy(v->name, "FM", sizeof(v->name)); 235 - v->type = V4L2_TUNER_RADIO; 236 - v->rangelow = 87 * 16000; 237 - v->rangehigh = 108 * 16000; 238 - v->rxsubchans = V4L2_TUNER_SUB_MONO; 239 - v->capability = V4L2_TUNER_CAP_LOW; 240 - v->audmode = V4L2_TUNER_MODE_MONO; 241 - v->signal = 0xffff * rt_getsigstr(rt); 242 - return 0; 243 - } 244 - 245 - static int vidioc_s_tuner(struct file *file, void *priv, 246 - struct v4l2_tuner *v) 247 - { 248 - return v->index ? -EINVAL : 0; 249 - } 250 - 251 - static int vidioc_s_frequency(struct file *file, void *priv, 252 - struct v4l2_frequency *f) 253 - { 254 - struct rtrack *rt = video_drvdata(file); 255 - 256 - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 257 - return -EINVAL; 258 - rt_setfreq(rt, f->frequency); 259 - return 0; 260 - } 261 - 262 - static int vidioc_g_frequency(struct file *file, void *priv, 263 - struct v4l2_frequency *f) 264 - { 265 - struct rtrack *rt = video_drvdata(file); 266 - 267 - if (f->tuner != 0) 268 - return -EINVAL; 269 - f->type = V4L2_TUNER_RADIO; 270 - f->frequency = rt->curfreq; 271 - return 0; 272 - } 273 - 274 - static int vidioc_queryctrl(struct file *file, void *priv, 275 - struct v4l2_queryctrl *qc) 276 - { 277 - switch (qc->id) { 278 - case V4L2_CID_AUDIO_MUTE: 279 - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 280 - case V4L2_CID_AUDIO_VOLUME: 281 - return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff); 282 - } 283 - return -EINVAL; 284 - } 285 - 286 - static int vidioc_g_ctrl(struct file *file, void *priv, 287 - struct v4l2_control *ctrl) 288 - { 289 - struct rtrack *rt = video_drvdata(file); 290 - 291 - switch (ctrl->id) { 292 - case V4L2_CID_AUDIO_MUTE: 293 - ctrl->value = rt->muted; 294 - return 0; 295 - case V4L2_CID_AUDIO_VOLUME: 296 - ctrl->value = rt->curvol; 140 + if (mute) { 141 + outb(0xd0, isa->io); /* volume steady + sigstr + off */ 297 142 return 0; 298 143 } 299 - return -EINVAL; 300 - } 301 - 302 - static int vidioc_s_ctrl(struct file *file, void *priv, 303 - struct v4l2_control *ctrl) 304 - { 305 - struct rtrack *rt = video_drvdata(file); 306 - 307 - switch (ctrl->id) { 308 - case V4L2_CID_AUDIO_MUTE: 309 - if (ctrl->value) 310 - rt_mute(rt); 311 - else 312 - rt_setvol(rt, rt->curvol); 313 - return 0; 314 - case V4L2_CID_AUDIO_VOLUME: 315 - rt_setvol(rt, ctrl->value); 316 - return 0; 144 + if (vol == 0) { /* volume = 0 means mute the card */ 145 + outb(0x48, isa->io); /* volume down but still "on" */ 146 + msleep(curvol * 3); /* make sure it's totally down */ 147 + } else if (curvol < vol) { 148 + outb(0x98, isa->io); /* volume up + sigstr + on */ 149 + for (; curvol < vol; curvol++) 150 + udelay(3000); 151 + } else if (curvol > vol) { 152 + outb(0x58, isa->io); /* volume down + sigstr + on */ 153 + for (; curvol > vol; curvol--) 154 + udelay(3000); 317 155 } 318 - return -EINVAL; 319 - } 320 - 321 - static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 322 - { 323 - *i = 0; 156 + outb(0xd8, isa->io); /* volume steady + sigstr + on */ 157 + rt->curvol = vol; 324 158 return 0; 325 159 } 326 160 327 - static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 161 + /* Mute card - prevents noisy bootups */ 162 + static int rtrack_initialize(struct radio_isa_card *isa) 328 163 { 329 - return i ? -EINVAL : 0; 330 - } 331 - 332 - static int vidioc_g_audio(struct file *file, void *priv, 333 - struct v4l2_audio *a) 334 - { 335 - a->index = 0; 336 - strlcpy(a->name, "Radio", sizeof(a->name)); 337 - a->capability = V4L2_AUDCAP_STEREO; 164 + /* this ensures that the volume is all the way up */ 165 + outb(0x90, isa->io); /* volume up but still "on" */ 166 + msleep(3000); /* make sure it's totally up */ 167 + outb(0xc0, isa->io); /* steady volume, mute card */ 338 168 return 0; 339 169 } 340 170 341 - static int vidioc_s_audio(struct file *file, void *priv, 342 - struct v4l2_audio *a) 343 - { 344 - return a->index ? -EINVAL : 0; 345 - } 346 - 347 - static const struct v4l2_file_operations rtrack_fops = { 348 - .owner = THIS_MODULE, 349 - .unlocked_ioctl = video_ioctl2, 171 + static const struct radio_isa_ops rtrack_ops = { 172 + .alloc = rtrack_alloc, 173 + .init = rtrack_initialize, 174 + .s_mute_volume = rtrack_s_mute_volume, 175 + .s_frequency = rtrack_s_frequency, 176 + .g_signal = rtrack_g_signal, 350 177 }; 351 178 352 - static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { 353 - .vidioc_querycap = vidioc_querycap, 354 - .vidioc_g_tuner = vidioc_g_tuner, 355 - .vidioc_s_tuner = vidioc_s_tuner, 356 - .vidioc_g_audio = vidioc_g_audio, 357 - .vidioc_s_audio = vidioc_s_audio, 358 - .vidioc_g_input = vidioc_g_input, 359 - .vidioc_s_input = vidioc_s_input, 360 - .vidioc_g_frequency = vidioc_g_frequency, 361 - .vidioc_s_frequency = vidioc_s_frequency, 362 - .vidioc_queryctrl = vidioc_queryctrl, 363 - .vidioc_g_ctrl = vidioc_g_ctrl, 364 - .vidioc_s_ctrl = vidioc_s_ctrl, 179 + static const int rtrack_ioports[] = { 0x20f, 0x30f }; 180 + 181 + static struct radio_isa_driver rtrack_driver = { 182 + .driver = { 183 + .match = radio_isa_match, 184 + .probe = radio_isa_probe, 185 + .remove = radio_isa_remove, 186 + .driver = { 187 + .name = "radio-aimslab", 188 + }, 189 + }, 190 + .io_params = io, 191 + .radio_nr_params = radio_nr, 192 + .io_ports = rtrack_ioports, 193 + .num_of_io_ports = ARRAY_SIZE(rtrack_ioports), 194 + .region_size = 2, 195 + .card = "AIMSlab RadioTrack/RadioReveal", 196 + .ops = &rtrack_ops, 197 + .has_stereo = true, 198 + .max_volume = 0xff, 365 199 }; 366 200 367 201 static int __init rtrack_init(void) 368 202 { 369 - struct rtrack *rt = &rtrack_card; 370 - struct v4l2_device *v4l2_dev = &rt->v4l2_dev; 371 - int res; 372 - 373 - strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name)); 374 - rt->io = io; 375 - 376 - if (rt->io == -1) { 377 - v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n"); 378 - return -EINVAL; 379 - } 380 - 381 - if (!request_region(rt->io, 2, "rtrack")) { 382 - v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io); 383 - return -EBUSY; 384 - } 385 - 386 - res = v4l2_device_register(NULL, v4l2_dev); 387 - if (res < 0) { 388 - release_region(rt->io, 2); 389 - v4l2_err(v4l2_dev, "could not register v4l2_device\n"); 390 - return res; 391 - } 392 - 393 - strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name)); 394 - rt->vdev.v4l2_dev = v4l2_dev; 395 - rt->vdev.fops = &rtrack_fops; 396 - rt->vdev.ioctl_ops = &rtrack_ioctl_ops; 397 - rt->vdev.release = video_device_release_empty; 398 - video_set_drvdata(&rt->vdev, rt); 399 - 400 - /* Set up the I/O locking */ 401 - 402 - mutex_init(&rt->lock); 403 - 404 - /* mute card - prevents noisy bootups */ 405 - 406 - /* this ensures that the volume is all the way down */ 407 - outb(0x48, rt->io); /* volume down but still "on" */ 408 - msleep(2000); /* make sure it's totally down */ 409 - outb(0xc0, rt->io); /* steady volume, mute card */ 410 - 411 - if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 412 - v4l2_device_unregister(&rt->v4l2_dev); 413 - release_region(rt->io, 2); 414 - return -EINVAL; 415 - } 416 - v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); 417 - 418 - return 0; 203 + return isa_register_driver(&rtrack_driver.driver, RTRACK_MAX); 419 204 } 420 205 421 206 static void __exit rtrack_exit(void) 422 207 { 423 - struct rtrack *rt = &rtrack_card; 424 - 425 - video_unregister_device(&rt->vdev); 426 - v4l2_device_unregister(&rt->v4l2_dev); 427 - release_region(rt->io, 2); 208 + isa_unregister_driver(&rtrack_driver.driver); 428 209 } 429 210 430 211 module_init(rtrack_init); 431 212 module_exit(rtrack_exit); 432 -
+88 -300
drivers/media/radio/radio-aztech.c
··· 1 - /* radio-aztech.c - Aztech radio card driver for Linux 2.2 1 + /* 2 + * radio-aztech.c - Aztech radio card driver 2 3 * 4 + * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@xs4all.nl> 3 5 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 4 6 * Adapted to support the Video for Linux API by 5 7 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: ··· 12 10 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) 13 11 * William McGrath (wmcgrath@twilight.vtc.vsc.edu) 14 12 * 15 - * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/ 16 - * along with more information on the card itself. 17 - * 18 - * History: 19 - * 1999-02-24 Russell Kroll <rkroll@exploits.org> 20 - * Fine tuning/VIDEO_TUNER_LOW 21 - * Range expanded to 87-108 MHz (from 87.9-107.8) 22 - * 23 - * Notable changes from the original source: 24 - * - includes stripped down to the essentials 25 - * - for loops used as delays replaced with udelay() 26 - * - #defines removed, changed to static values 27 - * - tuning structure changed - no more character arrays, other changes 13 + * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool. 28 14 */ 29 15 30 16 #include <linux/module.h> /* Modules */ ··· 21 31 #include <linux/delay.h> /* udelay */ 22 32 #include <linux/videodev2.h> /* kernel radio structs */ 23 33 #include <linux/io.h> /* outb, outb_p */ 34 + #include <linux/slab.h> 24 35 #include <media/v4l2-device.h> 25 36 #include <media/v4l2-ioctl.h> 37 + #include <media/v4l2-ctrls.h> 38 + #include "radio-isa.h" 26 39 27 40 MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); 28 41 MODULE_DESCRIPTION("A driver for the Aztech radio card."); 29 42 MODULE_LICENSE("GPL"); 30 - MODULE_VERSION("0.0.3"); 43 + MODULE_VERSION("1.0.0"); 31 44 32 45 /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ 33 - 34 46 #ifndef CONFIG_RADIO_AZTECH_PORT 35 47 #define CONFIG_RADIO_AZTECH_PORT -1 36 48 #endif 37 49 38 - static int io = CONFIG_RADIO_AZTECH_PORT; 39 - static int radio_nr = -1; 40 - static int radio_wait_time = 1000; 50 + #define AZTECH_MAX 2 41 51 42 - module_param(io, int, 0); 43 - module_param(radio_nr, int, 0); 44 - MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)"); 52 + static int io[AZTECH_MAX] = { [0] = CONFIG_RADIO_AZTECH_PORT, 53 + [1 ... (AZTECH_MAX - 1)] = -1 }; 54 + static int radio_nr[AZTECH_MAX] = { [0 ... (AZTECH_MAX - 1)] = -1 }; 55 + static const int radio_wait_time = 1000; 45 56 46 - struct aztech 47 - { 48 - struct v4l2_device v4l2_dev; 49 - struct video_device vdev; 50 - int io; 57 + module_param_array(io, int, NULL, 0444); 58 + MODULE_PARM_DESC(io, "I/O addresses of the Aztech card (0x350 or 0x358)"); 59 + module_param_array(radio_nr, int, NULL, 0444); 60 + MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 61 + 62 + struct aztech { 63 + struct radio_isa_card isa; 51 64 int curvol; 52 - unsigned long curfreq; 53 - int stereo; 54 - struct mutex lock; 55 65 }; 56 - 57 - static struct aztech aztech_card; 58 - 59 - static int volconvert(int level) 60 - { 61 - level >>= 14; /* Map 16bits down to 2 bit */ 62 - level &= 3; 63 - 64 - /* convert to card-friendly values */ 65 - switch (level) { 66 - case 0: 67 - return 0; 68 - case 1: 69 - return 1; 70 - case 2: 71 - return 4; 72 - case 3: 73 - return 5; 74 - } 75 - return 0; /* Quieten gcc */ 76 - } 77 66 78 67 static void send_0_byte(struct aztech *az) 79 68 { 80 69 udelay(radio_wait_time); 81 - outb_p(2 + volconvert(az->curvol), az->io); 82 - outb_p(64 + 2 + volconvert(az->curvol), az->io); 70 + outb_p(2 + az->curvol, az->isa.io); 71 + outb_p(64 + 2 + az->curvol, az->isa.io); 83 72 } 84 73 85 74 static void send_1_byte(struct aztech *az) 86 75 { 87 - udelay (radio_wait_time); 88 - outb_p(128 + 2 + volconvert(az->curvol), az->io); 89 - outb_p(128 + 64 + 2 + volconvert(az->curvol), az->io); 76 + udelay(radio_wait_time); 77 + outb_p(128 + 2 + az->curvol, az->isa.io); 78 + outb_p(128 + 64 + 2 + az->curvol, az->isa.io); 90 79 } 91 80 92 - static int az_setvol(struct aztech *az, int vol) 81 + static struct radio_isa_card *aztech_alloc(void) 93 82 { 94 - mutex_lock(&az->lock); 95 - outb(volconvert(vol), az->io); 96 - mutex_unlock(&az->lock); 97 - return 0; 83 + struct aztech *az = kzalloc(sizeof(*az), GFP_KERNEL); 84 + 85 + return az ? &az->isa : NULL; 98 86 } 99 87 100 - /* thanks to Michael Dwyer for giving me a dose of clues in 101 - * the signal strength department.. 102 - * 103 - * This card has a stereo bit - bit 0 set = mono, not set = stereo 104 - * It also has a "signal" bit - bit 1 set = bad signal, not set = good 105 - * 106 - */ 107 - 108 - static int az_getsigstr(struct aztech *az) 88 + static int aztech_s_frequency(struct radio_isa_card *isa, u32 freq) 109 89 { 110 - int sig = 1; 111 - 112 - mutex_lock(&az->lock); 113 - if (inb(az->io) & 2) /* bit set = no signal present */ 114 - sig = 0; 115 - mutex_unlock(&az->lock); 116 - return sig; 117 - } 118 - 119 - static int az_getstereo(struct aztech *az) 120 - { 121 - int stereo = 1; 122 - 123 - mutex_lock(&az->lock); 124 - if (inb(az->io) & 1) /* bit set = mono */ 125 - stereo = 0; 126 - mutex_unlock(&az->lock); 127 - return stereo; 128 - } 129 - 130 - static int az_setfreq(struct aztech *az, unsigned long frequency) 131 - { 90 + struct aztech *az = container_of(isa, struct aztech, isa); 132 91 int i; 133 92 134 - mutex_lock(&az->lock); 135 - 136 - az->curfreq = frequency; 137 - frequency += 171200; /* Add 10.7 MHz IF */ 138 - frequency /= 800; /* Convert to 50 kHz units */ 93 + freq += 171200; /* Add 10.7 MHz IF */ 94 + freq /= 800; /* Convert to 50 kHz units */ 139 95 140 96 send_0_byte(az); /* 0: LSB of frequency */ 141 97 142 98 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ 143 - if (frequency & (1 << i)) 99 + if (freq & (1 << i)) 144 100 send_1_byte(az); 145 101 else 146 102 send_0_byte(az); ··· 94 158 send_0_byte(az); /* 14: test bit - always 0 */ 95 159 send_0_byte(az); /* 15: test bit - always 0 */ 96 160 send_0_byte(az); /* 16: band data 0 - always 0 */ 97 - if (az->stereo) /* 17: stereo (1 to enable) */ 161 + if (isa->stereo) /* 17: stereo (1 to enable) */ 98 162 send_1_byte(az); 99 163 else 100 164 send_0_byte(az); ··· 109 173 /* latch frequency */ 110 174 111 175 udelay(radio_wait_time); 112 - outb_p(128 + 64 + volconvert(az->curvol), az->io); 113 - 114 - mutex_unlock(&az->lock); 176 + outb_p(128 + 64 + az->curvol, az->isa.io); 115 177 116 178 return 0; 117 179 } 118 180 119 - static int vidioc_querycap(struct file *file, void *priv, 120 - struct v4l2_capability *v) 181 + /* thanks to Michael Dwyer for giving me a dose of clues in 182 + * the signal strength department.. 183 + * 184 + * This card has a stereo bit - bit 0 set = mono, not set = stereo 185 + */ 186 + static u32 aztech_g_rxsubchans(struct radio_isa_card *isa) 121 187 { 122 - strlcpy(v->driver, "radio-aztech", sizeof(v->driver)); 123 - strlcpy(v->card, "Aztech Radio", sizeof(v->card)); 124 - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 125 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 188 + if (inb(isa->io) & 1) 189 + return V4L2_TUNER_SUB_MONO; 190 + return V4L2_TUNER_SUB_STEREO; 191 + } 192 + 193 + static int aztech_s_stereo(struct radio_isa_card *isa, bool stereo) 194 + { 195 + return aztech_s_frequency(isa, isa->freq); 196 + } 197 + 198 + static int aztech_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) 199 + { 200 + struct aztech *az = container_of(isa, struct aztech, isa); 201 + 202 + if (mute) 203 + vol = 0; 204 + az->curvol = (vol & 1) + ((vol & 2) << 1); 205 + outb(az->curvol, isa->io); 126 206 return 0; 127 207 } 128 208 129 - static int vidioc_g_tuner(struct file *file, void *priv, 130 - struct v4l2_tuner *v) 131 - { 132 - struct aztech *az = video_drvdata(file); 133 - 134 - if (v->index > 0) 135 - return -EINVAL; 136 - 137 - strlcpy(v->name, "FM", sizeof(v->name)); 138 - v->type = V4L2_TUNER_RADIO; 139 - 140 - v->rangelow = 87 * 16000; 141 - v->rangehigh = 108 * 16000; 142 - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 143 - v->capability = V4L2_TUNER_CAP_LOW; 144 - if (az_getstereo(az)) 145 - v->audmode = V4L2_TUNER_MODE_STEREO; 146 - else 147 - v->audmode = V4L2_TUNER_MODE_MONO; 148 - v->signal = 0xFFFF * az_getsigstr(az); 149 - 150 - return 0; 151 - } 152 - 153 - static int vidioc_s_tuner(struct file *file, void *priv, 154 - struct v4l2_tuner *v) 155 - { 156 - return v->index ? -EINVAL : 0; 157 - } 158 - 159 - static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 160 - { 161 - *i = 0; 162 - return 0; 163 - } 164 - 165 - static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 166 - { 167 - return i ? -EINVAL : 0; 168 - } 169 - 170 - static int vidioc_g_audio(struct file *file, void *priv, 171 - struct v4l2_audio *a) 172 - { 173 - a->index = 0; 174 - strlcpy(a->name, "Radio", sizeof(a->name)); 175 - a->capability = V4L2_AUDCAP_STEREO; 176 - return 0; 177 - } 178 - 179 - static int vidioc_s_audio(struct file *file, void *priv, 180 - struct v4l2_audio *a) 181 - { 182 - return a->index ? -EINVAL : 0; 183 - } 184 - 185 - static int vidioc_s_frequency(struct file *file, void *priv, 186 - struct v4l2_frequency *f) 187 - { 188 - struct aztech *az = video_drvdata(file); 189 - 190 - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 191 - return -EINVAL; 192 - az_setfreq(az, f->frequency); 193 - return 0; 194 - } 195 - 196 - static int vidioc_g_frequency(struct file *file, void *priv, 197 - struct v4l2_frequency *f) 198 - { 199 - struct aztech *az = video_drvdata(file); 200 - 201 - if (f->tuner != 0) 202 - return -EINVAL; 203 - f->type = V4L2_TUNER_RADIO; 204 - f->frequency = az->curfreq; 205 - return 0; 206 - } 207 - 208 - static int vidioc_queryctrl(struct file *file, void *priv, 209 - struct v4l2_queryctrl *qc) 210 - { 211 - switch (qc->id) { 212 - case V4L2_CID_AUDIO_MUTE: 213 - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 214 - case V4L2_CID_AUDIO_VOLUME: 215 - return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff); 216 - } 217 - return -EINVAL; 218 - } 219 - 220 - static int vidioc_g_ctrl(struct file *file, void *priv, 221 - struct v4l2_control *ctrl) 222 - { 223 - struct aztech *az = video_drvdata(file); 224 - 225 - switch (ctrl->id) { 226 - case V4L2_CID_AUDIO_MUTE: 227 - if (az->curvol == 0) 228 - ctrl->value = 1; 229 - else 230 - ctrl->value = 0; 231 - return 0; 232 - case V4L2_CID_AUDIO_VOLUME: 233 - ctrl->value = az->curvol * 6554; 234 - return 0; 235 - } 236 - return -EINVAL; 237 - } 238 - 239 - static int vidioc_s_ctrl(struct file *file, void *priv, 240 - struct v4l2_control *ctrl) 241 - { 242 - struct aztech *az = video_drvdata(file); 243 - 244 - switch (ctrl->id) { 245 - case V4L2_CID_AUDIO_MUTE: 246 - if (ctrl->value) 247 - az_setvol(az, 0); 248 - else 249 - az_setvol(az, az->curvol); 250 - return 0; 251 - case V4L2_CID_AUDIO_VOLUME: 252 - az_setvol(az, ctrl->value); 253 - return 0; 254 - } 255 - return -EINVAL; 256 - } 257 - 258 - static const struct v4l2_file_operations aztech_fops = { 259 - .owner = THIS_MODULE, 260 - .unlocked_ioctl = video_ioctl2, 209 + static const struct radio_isa_ops aztech_ops = { 210 + .alloc = aztech_alloc, 211 + .s_mute_volume = aztech_s_mute_volume, 212 + .s_frequency = aztech_s_frequency, 213 + .s_stereo = aztech_s_stereo, 214 + .g_rxsubchans = aztech_g_rxsubchans, 261 215 }; 262 216 263 - static const struct v4l2_ioctl_ops aztech_ioctl_ops = { 264 - .vidioc_querycap = vidioc_querycap, 265 - .vidioc_g_tuner = vidioc_g_tuner, 266 - .vidioc_s_tuner = vidioc_s_tuner, 267 - .vidioc_g_audio = vidioc_g_audio, 268 - .vidioc_s_audio = vidioc_s_audio, 269 - .vidioc_g_input = vidioc_g_input, 270 - .vidioc_s_input = vidioc_s_input, 271 - .vidioc_g_frequency = vidioc_g_frequency, 272 - .vidioc_s_frequency = vidioc_s_frequency, 273 - .vidioc_queryctrl = vidioc_queryctrl, 274 - .vidioc_g_ctrl = vidioc_g_ctrl, 275 - .vidioc_s_ctrl = vidioc_s_ctrl, 217 + static const int aztech_ioports[] = { 0x350, 0x358 }; 218 + 219 + static struct radio_isa_driver aztech_driver = { 220 + .driver = { 221 + .match = radio_isa_match, 222 + .probe = radio_isa_probe, 223 + .remove = radio_isa_remove, 224 + .driver = { 225 + .name = "radio-aztech", 226 + }, 227 + }, 228 + .io_params = io, 229 + .radio_nr_params = radio_nr, 230 + .io_ports = aztech_ioports, 231 + .num_of_io_ports = ARRAY_SIZE(aztech_ioports), 232 + .region_size = 2, 233 + .card = "Aztech Radio", 234 + .ops = &aztech_ops, 235 + .has_stereo = true, 236 + .max_volume = 3, 276 237 }; 277 238 278 239 static int __init aztech_init(void) 279 240 { 280 - struct aztech *az = &aztech_card; 281 - struct v4l2_device *v4l2_dev = &az->v4l2_dev; 282 - int res; 283 - 284 - strlcpy(v4l2_dev->name, "aztech", sizeof(v4l2_dev->name)); 285 - az->io = io; 286 - 287 - if (az->io == -1) { 288 - v4l2_err(v4l2_dev, "you must set an I/O address with io=0x350 or 0x358\n"); 289 - return -EINVAL; 290 - } 291 - 292 - if (!request_region(az->io, 2, "aztech")) { 293 - v4l2_err(v4l2_dev, "port 0x%x already in use\n", az->io); 294 - return -EBUSY; 295 - } 296 - 297 - res = v4l2_device_register(NULL, v4l2_dev); 298 - if (res < 0) { 299 - release_region(az->io, 2); 300 - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 301 - return res; 302 - } 303 - 304 - mutex_init(&az->lock); 305 - strlcpy(az->vdev.name, v4l2_dev->name, sizeof(az->vdev.name)); 306 - az->vdev.v4l2_dev = v4l2_dev; 307 - az->vdev.fops = &aztech_fops; 308 - az->vdev.ioctl_ops = &aztech_ioctl_ops; 309 - az->vdev.release = video_device_release_empty; 310 - video_set_drvdata(&az->vdev, az); 311 - /* mute card - prevents noisy bootups */ 312 - outb(0, az->io); 313 - 314 - if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 315 - v4l2_device_unregister(v4l2_dev); 316 - release_region(az->io, 2); 317 - return -EINVAL; 318 - } 319 - 320 - v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); 321 - return 0; 241 + return isa_register_driver(&aztech_driver.driver, AZTECH_MAX); 322 242 } 323 243 324 244 static void __exit aztech_exit(void) 325 245 { 326 - struct aztech *az = &aztech_card; 327 - 328 - video_unregister_device(&az->vdev); 329 - v4l2_device_unregister(&az->v4l2_dev); 330 - release_region(az->io, 2); 246 + isa_unregister_driver(&aztech_driver.driver); 331 247 } 332 248 333 249 module_init(aztech_init);
+101 -397
drivers/media/radio/radio-gemtek.c
··· 1 - /* GemTek radio card driver for Linux (C) 1998 Jonas Munsin <jmunsin@iki.fi> 1 + /* 2 + * GemTek radio card driver 3 + * 4 + * Copyright 1998 Jonas Munsin <jmunsin@iki.fi> 2 5 * 3 6 * GemTek hasn't released any specs on the card, so the protocol had to 4 7 * be reverse engineered with dosemu. ··· 14 11 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> 15 12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 16 13 * 17 - * TODO: Allow for more than one of these foolish entities :-) 18 - * 14 + * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> 19 15 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 16 + * 17 + * Note: this card seems to swap the left and right audio channels! 18 + * 19 + * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool. 20 20 */ 21 21 22 22 #include <linux/module.h> /* Modules */ ··· 29 23 #include <linux/videodev2.h> /* kernel radio structs */ 30 24 #include <linux/mutex.h> 31 25 #include <linux/io.h> /* outb, outb_p */ 26 + #include <linux/slab.h> 32 27 #include <media/v4l2-ioctl.h> 33 28 #include <media/v4l2-device.h> 29 + #include "radio-isa.h" 34 30 35 31 /* 36 32 * Module info. ··· 41 33 MODULE_AUTHOR("Jonas Munsin, Pekka Seppänen <pexu@kapsi.fi>"); 42 34 MODULE_DESCRIPTION("A driver for the GemTek Radio card."); 43 35 MODULE_LICENSE("GPL"); 44 - MODULE_VERSION("0.0.4"); 36 + MODULE_VERSION("1.0.0"); 45 37 46 38 /* 47 39 * Module params. ··· 54 46 #define CONFIG_RADIO_GEMTEK_PROBE 1 55 47 #endif 56 48 57 - static int io = CONFIG_RADIO_GEMTEK_PORT; 58 - static bool probe = CONFIG_RADIO_GEMTEK_PROBE; 59 - static bool hardmute; 60 - static bool shutdown = 1; 61 - static bool keepmuted = 1; 62 - static bool initmute = 1; 63 - static int radio_nr = -1; 49 + #define GEMTEK_MAX 4 64 50 65 - module_param(io, int, 0444); 66 - MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic " 51 + static bool probe = CONFIG_RADIO_GEMTEK_PROBE; 52 + static bool hardmute; 53 + static int io[GEMTEK_MAX] = { [0] = CONFIG_RADIO_GEMTEK_PORT, 54 + [1 ... (GEMTEK_MAX - 1)] = -1 }; 55 + static int radio_nr[GEMTEK_MAX] = { [0 ... (GEMTEK_MAX - 1)] = -1 }; 56 + 57 + module_param(probe, bool, 0444); 58 + MODULE_PARM_DESC(probe, "Enable automatic device probing."); 59 + 60 + module_param(hardmute, bool, 0644); 61 + MODULE_PARM_DESC(hardmute, "Enable 'hard muting' by shutting down PLL, may " 62 + "reduce static noise."); 63 + 64 + module_param_array(io, int, NULL, 0444); 65 + MODULE_PARM_DESC(io, "Force I/O ports for the GemTek Radio card if automatic " 67 66 "probing is disabled or fails. The most common I/O ports are: 0x20c " 68 67 "0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to " 69 68 "work for the combined sound/radiocard)."); 70 69 71 - module_param(probe, bool, 0444); 72 - MODULE_PARM_DESC(probe, "Enable automatic device probing. Note: only the most " 73 - "common I/O ports used by the card are probed."); 74 - 75 - module_param(hardmute, bool, 0644); 76 - MODULE_PARM_DESC(hardmute, "Enable `hard muting' by shutting down PLL, may " 77 - "reduce static noise."); 78 - 79 - module_param(shutdown, bool, 0644); 80 - MODULE_PARM_DESC(shutdown, "Enable shutting down PLL and muting line when " 81 - "module is unloaded."); 82 - 83 - module_param(keepmuted, bool, 0644); 84 - MODULE_PARM_DESC(keepmuted, "Keep card muted even when frequency is changed."); 85 - 86 - module_param(initmute, bool, 0444); 87 - MODULE_PARM_DESC(initmute, "Mute card when module is loaded."); 88 - 89 - module_param(radio_nr, int, 0444); 90 - 91 - /* 92 - * Functions for controlling the card. 93 - */ 94 - #define GEMTEK_LOWFREQ (87*16000) 95 - #define GEMTEK_HIGHFREQ (108*16000) 70 + module_param_array(radio_nr, int, NULL, 0444); 71 + MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 96 72 97 73 /* 98 74 * Frequency calculation constants. Intermediate frequency 10.52 MHz (nominal ··· 100 108 #define LONG_DELAY 75 /* usec */ 101 109 102 110 struct gemtek { 103 - struct v4l2_device v4l2_dev; 104 - struct video_device vdev; 105 - struct mutex lock; 106 - unsigned long lastfreq; 107 - int muted; 108 - int verified; 109 - int io; 111 + struct radio_isa_card isa; 112 + bool muted; 110 113 u32 bu2614data; 111 114 }; 112 - 113 - static struct gemtek gemtek_card; 114 115 115 116 #define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */ 116 117 #define BU2614_PORT_BITS 3 /* P0..P2, Output port control data */ ··· 151 166 */ 152 167 static void gemtek_bu2614_transmit(struct gemtek *gt) 153 168 { 169 + struct radio_isa_card *isa = &gt->isa; 154 170 int i, bit, q, mute; 155 - 156 - mutex_lock(&gt->lock); 157 171 158 172 mute = gt->muted ? GEMTEK_MT : 0x00; 159 173 160 - outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io); 161 - udelay(SHORT_DELAY); 162 - outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io); 174 + outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, isa->io); 163 175 udelay(LONG_DELAY); 164 176 165 177 for (i = 0, q = gt->bu2614data; i < 32; i++, q >>= 1) { 166 178 bit = (q & 1) ? GEMTEK_DA : 0; 167 - outb_p(mute | GEMTEK_CE | bit, gt->io); 179 + outb_p(mute | GEMTEK_CE | bit, isa->io); 168 180 udelay(SHORT_DELAY); 169 - outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, gt->io); 181 + outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, isa->io); 170 182 udelay(SHORT_DELAY); 171 183 } 172 184 173 - outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io); 185 + outb_p(mute | GEMTEK_DA | GEMTEK_CK, isa->io); 174 186 udelay(SHORT_DELAY); 175 - outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io); 176 - udelay(LONG_DELAY); 177 - 178 - mutex_unlock(&gt->lock); 179 187 } 180 188 181 189 /* ··· 176 198 */ 177 199 static unsigned long gemtek_convfreq(unsigned long freq) 178 200 { 179 - return ((freq<<FSCALE) + IF_OFFSET + REF_FREQ/2) / REF_FREQ; 201 + return ((freq << FSCALE) + IF_OFFSET + REF_FREQ / 2) / REF_FREQ; 202 + } 203 + 204 + static struct radio_isa_card *gemtek_alloc(void) 205 + { 206 + struct gemtek *gt = kzalloc(sizeof(*gt), GFP_KERNEL); 207 + 208 + if (gt) 209 + gt->muted = true; 210 + return gt ? &gt->isa : NULL; 180 211 } 181 212 182 213 /* 183 214 * Set FM-frequency. 184 215 */ 185 - static void gemtek_setfreq(struct gemtek *gt, unsigned long freq) 216 + static int gemtek_s_frequency(struct radio_isa_card *isa, u32 freq) 186 217 { 187 - if (keepmuted && hardmute && gt->muted) 188 - return; 218 + struct gemtek *gt = container_of(isa, struct gemtek, isa); 189 219 190 - freq = clamp_val(freq, GEMTEK_LOWFREQ, GEMTEK_HIGHFREQ); 191 - 192 - gt->lastfreq = freq; 193 - gt->muted = 0; 220 + if (hardmute && gt->muted) 221 + return 0; 194 222 195 223 gemtek_bu2614_set(gt, BU2614_PORT, 0); 196 224 gemtek_bu2614_set(gt, BU2614_FMES, 0); ··· 204 220 gemtek_bu2614_set(gt, BU2614_SWAL, 0); 205 221 gemtek_bu2614_set(gt, BU2614_FMUN, 1); /* GT bit set */ 206 222 gemtek_bu2614_set(gt, BU2614_TEST, 0); 207 - 208 223 gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_STDF_3_125_KHZ); 209 224 gemtek_bu2614_set(gt, BU2614_FREQ, gemtek_convfreq(freq)); 210 - 211 225 gemtek_bu2614_transmit(gt); 226 + return 0; 212 227 } 213 228 214 229 /* 215 230 * Set mute flag. 216 231 */ 217 - static void gemtek_mute(struct gemtek *gt) 232 + static int gemtek_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) 218 233 { 234 + struct gemtek *gt = container_of(isa, struct gemtek, isa); 219 235 int i; 220 236 221 - gt->muted = 1; 222 - 237 + gt->muted = mute; 223 238 if (hardmute) { 239 + if (!mute) 240 + return gemtek_s_frequency(isa, isa->freq); 241 + 224 242 /* Turn off PLL, disable data output */ 225 243 gemtek_bu2614_set(gt, BU2614_PORT, 0); 226 244 gemtek_bu2614_set(gt, BU2614_FMES, 0); /* CT bit off */ ··· 233 247 gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF); 234 248 gemtek_bu2614_set(gt, BU2614_FREQ, 0); 235 249 gemtek_bu2614_transmit(gt); 236 - return; 250 + return 0; 237 251 } 238 - 239 - mutex_lock(&gt->lock); 240 252 241 253 /* Read bus contents (CE, CK and DA). */ 242 - i = inb_p(gt->io); 254 + i = inb_p(isa->io); 243 255 /* Write it back with mute flag set. */ 244 - outb_p((i >> 5) | GEMTEK_MT, gt->io); 256 + outb_p((i >> 5) | (mute ? GEMTEK_MT : 0), isa->io); 245 257 udelay(SHORT_DELAY); 246 - 247 - mutex_unlock(&gt->lock); 258 + return 0; 248 259 } 249 260 250 - /* 251 - * Unset mute flag. 252 - */ 253 - static void gemtek_unmute(struct gemtek *gt) 261 + static u32 gemtek_g_rxsubchans(struct radio_isa_card *isa) 254 262 { 255 - int i; 256 - 257 - gt->muted = 0; 258 - if (hardmute) { 259 - /* Turn PLL back on. */ 260 - gemtek_setfreq(gt, gt->lastfreq); 261 - return; 262 - } 263 - mutex_lock(&gt->lock); 264 - 265 - i = inb_p(gt->io); 266 - outb_p(i >> 5, gt->io); 267 - udelay(SHORT_DELAY); 268 - 269 - mutex_unlock(&gt->lock); 270 - } 271 - 272 - /* 273 - * Get signal strength (= stereo status). 274 - */ 275 - static inline int gemtek_getsigstr(struct gemtek *gt) 276 - { 277 - int sig; 278 - 279 - mutex_lock(&gt->lock); 280 - sig = inb_p(gt->io) & GEMTEK_NS ? 0 : 1; 281 - mutex_unlock(&gt->lock); 282 - return sig; 263 + if (inb_p(isa->io) & GEMTEK_NS) 264 + return V4L2_TUNER_SUB_MONO; 265 + return V4L2_TUNER_SUB_STEREO; 283 266 } 284 267 285 268 /* 286 269 * Check if requested card acts like GemTek Radio card. 287 270 */ 288 - static int gemtek_verify(struct gemtek *gt, int port) 271 + static bool gemtek_probe(struct radio_isa_card *isa, int io) 289 272 { 290 273 int i, q; 291 274 292 - if (gt->verified == port) 293 - return 1; 294 - 295 - mutex_lock(&gt->lock); 296 - 297 - q = inb_p(port); /* Read bus contents before probing. */ 275 + q = inb_p(io); /* Read bus contents before probing. */ 298 276 /* Try to turn on CE, CK and DA respectively and check if card responds 299 277 properly. */ 300 278 for (i = 0; i < 3; ++i) { 301 - outb_p(1 << i, port); 279 + outb_p(1 << i, io); 302 280 udelay(SHORT_DELAY); 303 281 304 - if ((inb_p(port) & (~GEMTEK_NS)) != (0x17 | (1 << (i + 5)))) { 305 - mutex_unlock(&gt->lock); 306 - return 0; 307 - } 282 + if ((inb_p(io) & ~GEMTEK_NS) != (0x17 | (1 << (i + 5)))) 283 + return false; 308 284 } 309 - outb_p(q >> 5, port); /* Write bus contents back. */ 285 + outb_p(q >> 5, io); /* Write bus contents back. */ 310 286 udelay(SHORT_DELAY); 311 - 312 - mutex_unlock(&gt->lock); 313 - gt->verified = port; 314 - 315 - return 1; 287 + return true; 316 288 } 317 289 318 - /* 319 - * Automatic probing for card. 320 - */ 321 - static int gemtek_probe(struct gemtek *gt) 322 - { 323 - struct v4l2_device *v4l2_dev = &gt->v4l2_dev; 324 - int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c }; 325 - int i; 326 - 327 - if (!probe) { 328 - v4l2_info(v4l2_dev, "Automatic device probing disabled.\n"); 329 - return -1; 330 - } 331 - 332 - v4l2_info(v4l2_dev, "Automatic device probing enabled.\n"); 333 - 334 - for (i = 0; i < ARRAY_SIZE(ioports); ++i) { 335 - v4l2_info(v4l2_dev, "Trying I/O port 0x%x...\n", ioports[i]); 336 - 337 - if (!request_region(ioports[i], 1, "gemtek-probe")) { 338 - v4l2_warn(v4l2_dev, "I/O port 0x%x busy!\n", 339 - ioports[i]); 340 - continue; 341 - } 342 - 343 - if (gemtek_verify(gt, ioports[i])) { 344 - v4l2_info(v4l2_dev, "Card found from I/O port " 345 - "0x%x!\n", ioports[i]); 346 - 347 - release_region(ioports[i], 1); 348 - gt->io = ioports[i]; 349 - return gt->io; 350 - } 351 - 352 - release_region(ioports[i], 1); 353 - } 354 - 355 - v4l2_err(v4l2_dev, "Automatic probing failed!\n"); 356 - return -1; 357 - } 358 - 359 - /* 360 - * Video 4 Linux stuff. 361 - */ 362 - 363 - static const struct v4l2_file_operations gemtek_fops = { 364 - .owner = THIS_MODULE, 365 - .unlocked_ioctl = video_ioctl2, 290 + static const struct radio_isa_ops gemtek_ops = { 291 + .alloc = gemtek_alloc, 292 + .probe = gemtek_probe, 293 + .s_mute_volume = gemtek_s_mute_volume, 294 + .s_frequency = gemtek_s_frequency, 295 + .g_rxsubchans = gemtek_g_rxsubchans, 366 296 }; 367 297 368 - static int vidioc_querycap(struct file *file, void *priv, 369 - struct v4l2_capability *v) 370 - { 371 - strlcpy(v->driver, "radio-gemtek", sizeof(v->driver)); 372 - strlcpy(v->card, "GemTek", sizeof(v->card)); 373 - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 374 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 375 - return 0; 376 - } 298 + static const int gemtek_ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c }; 377 299 378 - static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) 379 - { 380 - struct gemtek *gt = video_drvdata(file); 381 - 382 - if (v->index > 0) 383 - return -EINVAL; 384 - 385 - strlcpy(v->name, "FM", sizeof(v->name)); 386 - v->type = V4L2_TUNER_RADIO; 387 - v->rangelow = GEMTEK_LOWFREQ; 388 - v->rangehigh = GEMTEK_HIGHFREQ; 389 - v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 390 - v->signal = 0xffff * gemtek_getsigstr(gt); 391 - if (v->signal) { 392 - v->audmode = V4L2_TUNER_MODE_STEREO; 393 - v->rxsubchans = V4L2_TUNER_SUB_STEREO; 394 - } else { 395 - v->audmode = V4L2_TUNER_MODE_MONO; 396 - v->rxsubchans = V4L2_TUNER_SUB_MONO; 397 - } 398 - return 0; 399 - } 400 - 401 - static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) 402 - { 403 - return (v->index != 0) ? -EINVAL : 0; 404 - } 405 - 406 - static int vidioc_g_frequency(struct file *file, void *priv, 407 - struct v4l2_frequency *f) 408 - { 409 - struct gemtek *gt = video_drvdata(file); 410 - 411 - if (f->tuner != 0) 412 - return -EINVAL; 413 - f->type = V4L2_TUNER_RADIO; 414 - f->frequency = gt->lastfreq; 415 - return 0; 416 - } 417 - 418 - static int vidioc_s_frequency(struct file *file, void *priv, 419 - struct v4l2_frequency *f) 420 - { 421 - struct gemtek *gt = video_drvdata(file); 422 - 423 - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 424 - return -EINVAL; 425 - gemtek_setfreq(gt, f->frequency); 426 - return 0; 427 - } 428 - 429 - static int vidioc_queryctrl(struct file *file, void *priv, 430 - struct v4l2_queryctrl *qc) 431 - { 432 - switch (qc->id) { 433 - case V4L2_CID_AUDIO_MUTE: 434 - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); 435 - default: 436 - return -EINVAL; 437 - } 438 - } 439 - 440 - static int vidioc_g_ctrl(struct file *file, void *priv, 441 - struct v4l2_control *ctrl) 442 - { 443 - struct gemtek *gt = video_drvdata(file); 444 - 445 - switch (ctrl->id) { 446 - case V4L2_CID_AUDIO_MUTE: 447 - ctrl->value = gt->muted; 448 - return 0; 449 - } 450 - return -EINVAL; 451 - } 452 - 453 - static int vidioc_s_ctrl(struct file *file, void *priv, 454 - struct v4l2_control *ctrl) 455 - { 456 - struct gemtek *gt = video_drvdata(file); 457 - 458 - switch (ctrl->id) { 459 - case V4L2_CID_AUDIO_MUTE: 460 - if (ctrl->value) 461 - gemtek_mute(gt); 462 - else 463 - gemtek_unmute(gt); 464 - return 0; 465 - } 466 - return -EINVAL; 467 - } 468 - 469 - static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 470 - { 471 - *i = 0; 472 - return 0; 473 - } 474 - 475 - static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 476 - { 477 - return (i != 0) ? -EINVAL : 0; 478 - } 479 - 480 - static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) 481 - { 482 - a->index = 0; 483 - strlcpy(a->name, "Radio", sizeof(a->name)); 484 - a->capability = V4L2_AUDCAP_STEREO; 485 - return 0; 486 - } 487 - 488 - static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) 489 - { 490 - return (a->index != 0) ? -EINVAL : 0; 491 - } 492 - 493 - static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { 494 - .vidioc_querycap = vidioc_querycap, 495 - .vidioc_g_tuner = vidioc_g_tuner, 496 - .vidioc_s_tuner = vidioc_s_tuner, 497 - .vidioc_g_audio = vidioc_g_audio, 498 - .vidioc_s_audio = vidioc_s_audio, 499 - .vidioc_g_input = vidioc_g_input, 500 - .vidioc_s_input = vidioc_s_input, 501 - .vidioc_g_frequency = vidioc_g_frequency, 502 - .vidioc_s_frequency = vidioc_s_frequency, 503 - .vidioc_queryctrl = vidioc_queryctrl, 504 - .vidioc_g_ctrl = vidioc_g_ctrl, 505 - .vidioc_s_ctrl = vidioc_s_ctrl 300 + static struct radio_isa_driver gemtek_driver = { 301 + .driver = { 302 + .match = radio_isa_match, 303 + .probe = radio_isa_probe, 304 + .remove = radio_isa_remove, 305 + .driver = { 306 + .name = "radio-gemtek", 307 + }, 308 + }, 309 + .io_params = io, 310 + .radio_nr_params = radio_nr, 311 + .io_ports = gemtek_ioports, 312 + .num_of_io_ports = ARRAY_SIZE(gemtek_ioports), 313 + .region_size = 1, 314 + .card = "GemTek Radio", 315 + .ops = &gemtek_ops, 316 + .has_stereo = true, 506 317 }; 507 - 508 - /* 509 - * Initialization / cleanup related stuff. 510 - */ 511 318 512 319 static int __init gemtek_init(void) 513 320 { 514 - struct gemtek *gt = &gemtek_card; 515 - struct v4l2_device *v4l2_dev = &gt->v4l2_dev; 516 - int res; 517 - 518 - strlcpy(v4l2_dev->name, "gemtek", sizeof(v4l2_dev->name)); 519 - 520 - v4l2_info(v4l2_dev, "GemTek Radio card driver: v0.0.3\n"); 521 - 522 - mutex_init(&gt->lock); 523 - 524 - gt->verified = -1; 525 - gt->io = io; 526 - gemtek_probe(gt); 527 - if (gt->io) { 528 - if (!request_region(gt->io, 1, "gemtek")) { 529 - v4l2_err(v4l2_dev, "I/O port 0x%x already in use.\n", gt->io); 530 - return -EBUSY; 531 - } 532 - 533 - if (!gemtek_verify(gt, gt->io)) 534 - v4l2_warn(v4l2_dev, "Card at I/O port 0x%x does not " 535 - "respond properly, check your " 536 - "configuration.\n", gt->io); 537 - else 538 - v4l2_info(v4l2_dev, "Using I/O port 0x%x.\n", gt->io); 539 - } else if (probe) { 540 - v4l2_err(v4l2_dev, "Automatic probing failed and no " 541 - "fixed I/O port defined.\n"); 542 - return -ENODEV; 543 - } else { 544 - v4l2_err(v4l2_dev, "Automatic probing disabled but no fixed " 545 - "I/O port defined."); 546 - return -EINVAL; 547 - } 548 - 549 - res = v4l2_device_register(NULL, v4l2_dev); 550 - if (res < 0) { 551 - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 552 - release_region(gt->io, 1); 553 - return res; 554 - } 555 - 556 - strlcpy(gt->vdev.name, v4l2_dev->name, sizeof(gt->vdev.name)); 557 - gt->vdev.v4l2_dev = v4l2_dev; 558 - gt->vdev.fops = &gemtek_fops; 559 - gt->vdev.ioctl_ops = &gemtek_ioctl_ops; 560 - gt->vdev.release = video_device_release_empty; 561 - video_set_drvdata(&gt->vdev, gt); 562 - 563 - /* Set defaults */ 564 - gt->lastfreq = GEMTEK_LOWFREQ; 565 - gt->bu2614data = 0; 566 - 567 - if (initmute) 568 - gemtek_mute(gt); 569 - 570 - if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 571 - v4l2_device_unregister(v4l2_dev); 572 - release_region(gt->io, 1); 573 - return -EBUSY; 574 - } 575 - 576 - return 0; 321 + gemtek_driver.probe = probe; 322 + return isa_register_driver(&gemtek_driver.driver, GEMTEK_MAX); 577 323 } 578 324 579 - /* 580 - * Module cleanup 581 - */ 582 325 static void __exit gemtek_exit(void) 583 326 { 584 - struct gemtek *gt = &gemtek_card; 585 - struct v4l2_device *v4l2_dev = &gt->v4l2_dev; 586 - 587 - if (shutdown) { 588 - hardmute = 1; /* Turn off PLL */ 589 - gemtek_mute(gt); 590 - } else { 591 - v4l2_info(v4l2_dev, "Module unloaded but card not muted!\n"); 592 - } 593 - 594 - video_unregister_device(&gt->vdev); 595 - v4l2_device_unregister(&gt->v4l2_dev); 596 - release_region(gt->io, 1); 327 + hardmute = 1; /* Turn off PLL */ 328 + isa_unregister_driver(&gemtek_driver.driver); 597 329 } 598 330 599 331 module_init(gemtek_init);
+340
drivers/media/radio/radio-isa.c
··· 1 + /* 2 + * Framework for ISA radio drivers. 3 + * This takes care of all the V4L2 scaffolding, allowing the ISA drivers 4 + * to concentrate on the actual hardware operation. 5 + * 6 + * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com> 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * version 2 as published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, but 13 + * WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 + * 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., 51 Franklin St, Fifth Floor, Boston, MA 20 + * 02110-1301 USA 21 + */ 22 + 23 + #include <linux/module.h> 24 + #include <linux/init.h> 25 + #include <linux/ioport.h> 26 + #include <linux/delay.h> 27 + #include <linux/videodev2.h> 28 + #include <linux/io.h> 29 + #include <linux/slab.h> 30 + #include <media/v4l2-device.h> 31 + #include <media/v4l2-ioctl.h> 32 + #include <media/v4l2-fh.h> 33 + #include <media/v4l2-ctrls.h> 34 + #include <media/v4l2-event.h> 35 + 36 + #include "radio-isa.h" 37 + 38 + MODULE_AUTHOR("Hans Verkuil"); 39 + MODULE_DESCRIPTION("A framework for ISA radio drivers."); 40 + MODULE_LICENSE("GPL"); 41 + 42 + #define FREQ_LOW (87U * 16000U) 43 + #define FREQ_HIGH (108U * 16000U) 44 + 45 + static int radio_isa_querycap(struct file *file, void *priv, 46 + struct v4l2_capability *v) 47 + { 48 + struct radio_isa_card *isa = video_drvdata(file); 49 + 50 + strlcpy(v->driver, isa->drv->driver.driver.name, sizeof(v->driver)); 51 + strlcpy(v->card, isa->drv->card, sizeof(v->card)); 52 + snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name); 53 + 54 + v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 55 + v->device_caps = v->capabilities | V4L2_CAP_DEVICE_CAPS; 56 + return 0; 57 + } 58 + 59 + static int radio_isa_g_tuner(struct file *file, void *priv, 60 + struct v4l2_tuner *v) 61 + { 62 + struct radio_isa_card *isa = video_drvdata(file); 63 + const struct radio_isa_ops *ops = isa->drv->ops; 64 + 65 + if (v->index > 0) 66 + return -EINVAL; 67 + 68 + strlcpy(v->name, "FM", sizeof(v->name)); 69 + v->type = V4L2_TUNER_RADIO; 70 + v->rangelow = FREQ_LOW; 71 + v->rangehigh = FREQ_HIGH; 72 + v->capability = V4L2_TUNER_CAP_LOW; 73 + if (isa->drv->has_stereo) 74 + v->capability |= V4L2_TUNER_CAP_STEREO; 75 + 76 + if (ops->g_rxsubchans) 77 + v->rxsubchans = ops->g_rxsubchans(isa); 78 + else 79 + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 80 + v->audmode = isa->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; 81 + if (ops->g_signal) 82 + v->signal = ops->g_signal(isa); 83 + else 84 + v->signal = (v->rxsubchans & V4L2_TUNER_SUB_STEREO) ? 85 + 0xffff : 0; 86 + return 0; 87 + } 88 + 89 + static int radio_isa_s_tuner(struct file *file, void *priv, 90 + struct v4l2_tuner *v) 91 + { 92 + struct radio_isa_card *isa = video_drvdata(file); 93 + const struct radio_isa_ops *ops = isa->drv->ops; 94 + 95 + if (v->index) 96 + return -EINVAL; 97 + if (ops->s_stereo) { 98 + isa->stereo = (v->audmode == V4L2_TUNER_MODE_STEREO); 99 + return ops->s_stereo(isa, isa->stereo); 100 + } 101 + return 0; 102 + } 103 + 104 + static int radio_isa_s_frequency(struct file *file, void *priv, 105 + struct v4l2_frequency *f) 106 + { 107 + struct radio_isa_card *isa = video_drvdata(file); 108 + int res; 109 + 110 + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 111 + return -EINVAL; 112 + f->frequency = clamp(f->frequency, FREQ_LOW, FREQ_HIGH); 113 + res = isa->drv->ops->s_frequency(isa, f->frequency); 114 + if (res == 0) 115 + isa->freq = f->frequency; 116 + return res; 117 + } 118 + 119 + static int radio_isa_g_frequency(struct file *file, void *priv, 120 + struct v4l2_frequency *f) 121 + { 122 + struct radio_isa_card *isa = video_drvdata(file); 123 + 124 + if (f->tuner != 0) 125 + return -EINVAL; 126 + f->type = V4L2_TUNER_RADIO; 127 + f->frequency = isa->freq; 128 + return 0; 129 + } 130 + 131 + static int radio_isa_s_ctrl(struct v4l2_ctrl *ctrl) 132 + { 133 + struct radio_isa_card *isa = 134 + container_of(ctrl->handler, struct radio_isa_card, hdl); 135 + 136 + switch (ctrl->id) { 137 + case V4L2_CID_AUDIO_MUTE: 138 + return isa->drv->ops->s_mute_volume(isa, ctrl->val, 139 + isa->volume ? isa->volume->val : 0); 140 + } 141 + return -EINVAL; 142 + } 143 + 144 + static int radio_isa_log_status(struct file *file, void *priv) 145 + { 146 + struct radio_isa_card *isa = video_drvdata(file); 147 + 148 + v4l2_info(&isa->v4l2_dev, "I/O Port = 0x%03x\n", isa->io); 149 + v4l2_ctrl_handler_log_status(&isa->hdl, isa->v4l2_dev.name); 150 + return 0; 151 + } 152 + 153 + static int radio_isa_subscribe_event(struct v4l2_fh *fh, 154 + struct v4l2_event_subscription *sub) 155 + { 156 + if (sub->type == V4L2_EVENT_CTRL) 157 + return v4l2_event_subscribe(fh, sub, 0); 158 + return -EINVAL; 159 + } 160 + 161 + static const struct v4l2_ctrl_ops radio_isa_ctrl_ops = { 162 + .s_ctrl = radio_isa_s_ctrl, 163 + }; 164 + 165 + static const struct v4l2_file_operations radio_isa_fops = { 166 + .owner = THIS_MODULE, 167 + .open = v4l2_fh_open, 168 + .release = v4l2_fh_release, 169 + .poll = v4l2_ctrl_poll, 170 + .unlocked_ioctl = video_ioctl2, 171 + }; 172 + 173 + static const struct v4l2_ioctl_ops radio_isa_ioctl_ops = { 174 + .vidioc_querycap = radio_isa_querycap, 175 + .vidioc_g_tuner = radio_isa_g_tuner, 176 + .vidioc_s_tuner = radio_isa_s_tuner, 177 + .vidioc_g_frequency = radio_isa_g_frequency, 178 + .vidioc_s_frequency = radio_isa_s_frequency, 179 + .vidioc_log_status = radio_isa_log_status, 180 + .vidioc_subscribe_event = radio_isa_subscribe_event, 181 + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 182 + }; 183 + 184 + int radio_isa_match(struct device *pdev, unsigned int dev) 185 + { 186 + struct radio_isa_driver *drv = pdev->platform_data; 187 + 188 + return drv->probe || drv->io_params[dev] >= 0; 189 + } 190 + EXPORT_SYMBOL_GPL(radio_isa_match); 191 + 192 + static bool radio_isa_valid_io(const struct radio_isa_driver *drv, int io) 193 + { 194 + int i; 195 + 196 + for (i = 0; i < drv->num_of_io_ports; i++) 197 + if (drv->io_ports[i] == io) 198 + return true; 199 + return false; 200 + } 201 + 202 + int radio_isa_probe(struct device *pdev, unsigned int dev) 203 + { 204 + struct radio_isa_driver *drv = pdev->platform_data; 205 + const struct radio_isa_ops *ops = drv->ops; 206 + struct v4l2_device *v4l2_dev; 207 + struct radio_isa_card *isa; 208 + int res; 209 + 210 + isa = drv->ops->alloc(); 211 + if (isa == NULL) 212 + return -ENOMEM; 213 + dev_set_drvdata(pdev, isa); 214 + isa->drv = drv; 215 + isa->io = drv->io_params[dev]; 216 + v4l2_dev = &isa->v4l2_dev; 217 + strlcpy(v4l2_dev->name, dev_name(pdev), sizeof(v4l2_dev->name)); 218 + 219 + if (drv->probe && ops->probe) { 220 + int i; 221 + 222 + for (i = 0; i < drv->num_of_io_ports; ++i) { 223 + int io = drv->io_ports[i]; 224 + 225 + if (request_region(io, drv->region_size, v4l2_dev->name)) { 226 + bool found = ops->probe(isa, io); 227 + 228 + release_region(io, drv->region_size); 229 + if (found) { 230 + isa->io = io; 231 + break; 232 + } 233 + } 234 + } 235 + } 236 + 237 + if (!radio_isa_valid_io(drv, isa->io)) { 238 + int i; 239 + 240 + if (isa->io < 0) 241 + return -ENODEV; 242 + v4l2_err(v4l2_dev, "you must set an I/O address with io=0x%03x", 243 + drv->io_ports[0]); 244 + for (i = 1; i < drv->num_of_io_ports; i++) 245 + printk(KERN_CONT "/0x%03x", drv->io_ports[i]); 246 + printk(KERN_CONT ".\n"); 247 + kfree(isa); 248 + return -EINVAL; 249 + } 250 + 251 + if (!request_region(isa->io, drv->region_size, v4l2_dev->name)) { 252 + v4l2_err(v4l2_dev, "port 0x%x already in use\n", isa->io); 253 + kfree(isa); 254 + return -EBUSY; 255 + } 256 + 257 + res = v4l2_device_register(pdev, v4l2_dev); 258 + if (res < 0) { 259 + v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 260 + goto err_dev_reg; 261 + } 262 + 263 + v4l2_ctrl_handler_init(&isa->hdl, 1); 264 + isa->mute = v4l2_ctrl_new_std(&isa->hdl, &radio_isa_ctrl_ops, 265 + V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); 266 + if (drv->max_volume) 267 + isa->volume = v4l2_ctrl_new_std(&isa->hdl, &radio_isa_ctrl_ops, 268 + V4L2_CID_AUDIO_VOLUME, 0, drv->max_volume, 1, 269 + drv->max_volume); 270 + v4l2_dev->ctrl_handler = &isa->hdl; 271 + if (isa->hdl.error) { 272 + res = isa->hdl.error; 273 + v4l2_err(v4l2_dev, "Could not register controls\n"); 274 + goto err_hdl; 275 + } 276 + if (drv->max_volume) 277 + v4l2_ctrl_cluster(2, &isa->mute); 278 + v4l2_dev->ctrl_handler = &isa->hdl; 279 + 280 + mutex_init(&isa->lock); 281 + isa->vdev.lock = &isa->lock; 282 + strlcpy(isa->vdev.name, v4l2_dev->name, sizeof(isa->vdev.name)); 283 + isa->vdev.v4l2_dev = v4l2_dev; 284 + isa->vdev.fops = &radio_isa_fops; 285 + isa->vdev.ioctl_ops = &radio_isa_ioctl_ops; 286 + isa->vdev.release = video_device_release_empty; 287 + set_bit(V4L2_FL_USE_FH_PRIO, &isa->vdev.flags); 288 + video_set_drvdata(&isa->vdev, isa); 289 + isa->freq = FREQ_LOW; 290 + isa->stereo = drv->has_stereo; 291 + 292 + if (ops->init) 293 + res = ops->init(isa); 294 + if (!res) 295 + res = v4l2_ctrl_handler_setup(&isa->hdl); 296 + if (!res) 297 + res = ops->s_frequency(isa, isa->freq); 298 + if (!res && ops->s_stereo) 299 + res = ops->s_stereo(isa, isa->stereo); 300 + if (res < 0) { 301 + v4l2_err(v4l2_dev, "Could not setup card\n"); 302 + goto err_node_reg; 303 + } 304 + res = video_register_device(&isa->vdev, VFL_TYPE_RADIO, 305 + drv->radio_nr_params[dev]); 306 + if (res < 0) { 307 + v4l2_err(v4l2_dev, "Could not register device node\n"); 308 + goto err_node_reg; 309 + } 310 + 311 + v4l2_info(v4l2_dev, "Initialized radio card %s on port 0x%03x\n", 312 + drv->card, isa->io); 313 + return 0; 314 + 315 + err_node_reg: 316 + v4l2_ctrl_handler_free(&isa->hdl); 317 + err_hdl: 318 + v4l2_device_unregister(&isa->v4l2_dev); 319 + err_dev_reg: 320 + release_region(isa->io, drv->region_size); 321 + kfree(isa); 322 + return res; 323 + } 324 + EXPORT_SYMBOL_GPL(radio_isa_probe); 325 + 326 + int radio_isa_remove(struct device *pdev, unsigned int dev) 327 + { 328 + struct radio_isa_card *isa = dev_get_drvdata(pdev); 329 + const struct radio_isa_ops *ops = isa->drv->ops; 330 + 331 + ops->s_mute_volume(isa, true, isa->volume ? isa->volume->cur.val : 0); 332 + video_unregister_device(&isa->vdev); 333 + v4l2_ctrl_handler_free(&isa->hdl); 334 + v4l2_device_unregister(&isa->v4l2_dev); 335 + release_region(isa->io, isa->drv->region_size); 336 + v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card); 337 + kfree(isa); 338 + return 0; 339 + } 340 + EXPORT_SYMBOL_GPL(radio_isa_remove);
+105
drivers/media/radio/radio-isa.h
··· 1 + /* 2 + * Framework for ISA radio drivers. 3 + * This takes care of all the V4L2 scaffolding, allowing the ISA drivers 4 + * to concentrate on the actual hardware operation. 5 + * 6 + * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com> 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * version 2 as published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, but 13 + * WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 + * 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., 51 Franklin St, Fifth Floor, Boston, MA 20 + * 02110-1301 USA 21 + */ 22 + 23 + #ifndef _RADIO_ISA_H_ 24 + #define _RADIO_ISA_H_ 25 + 26 + #include <linux/isa.h> 27 + #include <linux/videodev2.h> 28 + #include <media/v4l2-device.h> 29 + #include <media/v4l2-ctrls.h> 30 + 31 + struct radio_isa_driver; 32 + struct radio_isa_ops; 33 + 34 + /* Core structure for radio ISA cards */ 35 + struct radio_isa_card { 36 + const struct radio_isa_driver *drv; 37 + struct v4l2_device v4l2_dev; 38 + struct v4l2_ctrl_handler hdl; 39 + struct video_device vdev; 40 + struct mutex lock; 41 + const struct radio_isa_ops *ops; 42 + struct { /* mute/volume cluster */ 43 + struct v4l2_ctrl *mute; 44 + struct v4l2_ctrl *volume; 45 + }; 46 + /* I/O port */ 47 + int io; 48 + 49 + /* Card is in stereo audio mode */ 50 + bool stereo; 51 + /* Current frequency */ 52 + u32 freq; 53 + }; 54 + 55 + struct radio_isa_ops { 56 + /* Allocate and initialize a radio_isa_card struct */ 57 + struct radio_isa_card *(*alloc)(void); 58 + /* Probe whether a card is present at the given port */ 59 + bool (*probe)(struct radio_isa_card *isa, int io); 60 + /* Special card initialization can be done here, this is called after 61 + * the standard controls are registered, but before they are setup, 62 + * thus allowing drivers to add their own controls here. */ 63 + int (*init)(struct radio_isa_card *isa); 64 + /* Set mute and volume. */ 65 + int (*s_mute_volume)(struct radio_isa_card *isa, bool mute, int volume); 66 + /* Set frequency */ 67 + int (*s_frequency)(struct radio_isa_card *isa, u32 freq); 68 + /* Set stereo/mono audio mode */ 69 + int (*s_stereo)(struct radio_isa_card *isa, bool stereo); 70 + /* Get rxsubchans value for VIDIOC_G_TUNER */ 71 + u32 (*g_rxsubchans)(struct radio_isa_card *isa); 72 + /* Get the signal strength for VIDIOC_G_TUNER */ 73 + u32 (*g_signal)(struct radio_isa_card *isa); 74 + }; 75 + 76 + /* Top level structure needed to instantiate the cards */ 77 + struct radio_isa_driver { 78 + struct isa_driver driver; 79 + const struct radio_isa_ops *ops; 80 + /* The module_param_array with the specified I/O ports */ 81 + int *io_params; 82 + /* The module_param_array with the radio_nr values */ 83 + int *radio_nr_params; 84 + /* Whether we should probe for possible cards */ 85 + bool probe; 86 + /* The list of possible I/O ports */ 87 + const int *io_ports; 88 + /* The size of that list */ 89 + int num_of_io_ports; 90 + /* The region size to request */ 91 + unsigned region_size; 92 + /* The name of the card */ 93 + const char *card; 94 + /* Card can capture stereo audio */ 95 + bool has_stereo; 96 + /* The maximum volume for the volume control. If 0, then there 97 + is no volume control possible. */ 98 + int max_volume; 99 + }; 100 + 101 + int radio_isa_match(struct device *pdev, unsigned int dev); 102 + int radio_isa_probe(struct device *pdev, unsigned int dev); 103 + int radio_isa_remove(struct device *pdev, unsigned int dev); 104 + 105 + #endif
+427
drivers/media/radio/radio-keene.c
··· 1 + /* 2 + * Copyright (c) 2012 Hans Verkuil <hverkuil@xs4all.nl> 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; either version 2 of the License, or 7 + * (at your option) any later version. 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. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 + */ 18 + 19 + /* kernel includes */ 20 + #include <linux/kernel.h> 21 + #include <linux/module.h> 22 + #include <linux/init.h> 23 + #include <linux/slab.h> 24 + #include <linux/input.h> 25 + #include <linux/videodev2.h> 26 + #include <media/v4l2-device.h> 27 + #include <media/v4l2-ioctl.h> 28 + #include <media/v4l2-ctrls.h> 29 + #include <media/v4l2-event.h> 30 + #include <linux/usb.h> 31 + #include <linux/version.h> 32 + #include <linux/mutex.h> 33 + 34 + /* driver and module definitions */ 35 + MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>"); 36 + MODULE_DESCRIPTION("Keene FM Transmitter driver"); 37 + MODULE_LICENSE("GPL"); 38 + 39 + /* Actually, it advertises itself as a Logitech */ 40 + #define USB_KEENE_VENDOR 0x046d 41 + #define USB_KEENE_PRODUCT 0x0a0e 42 + 43 + /* Probably USB_TIMEOUT should be modified in module parameter */ 44 + #define BUFFER_LENGTH 8 45 + #define USB_TIMEOUT 500 46 + 47 + /* Frequency limits in MHz */ 48 + #define FREQ_MIN 76U 49 + #define FREQ_MAX 108U 50 + #define FREQ_MUL 16000U 51 + 52 + /* USB Device ID List */ 53 + static struct usb_device_id usb_keene_device_table[] = { 54 + {USB_DEVICE_AND_INTERFACE_INFO(USB_KEENE_VENDOR, USB_KEENE_PRODUCT, 55 + USB_CLASS_HID, 0, 0) }, 56 + { } /* Terminating entry */ 57 + }; 58 + 59 + MODULE_DEVICE_TABLE(usb, usb_keene_device_table); 60 + 61 + struct keene_device { 62 + struct usb_device *usbdev; 63 + struct usb_interface *intf; 64 + struct video_device vdev; 65 + struct v4l2_device v4l2_dev; 66 + struct v4l2_ctrl_handler hdl; 67 + struct mutex lock; 68 + 69 + u8 *buffer; 70 + unsigned curfreq; 71 + u8 tx; 72 + u8 pa; 73 + bool stereo; 74 + bool muted; 75 + bool preemph_75_us; 76 + }; 77 + 78 + static inline struct keene_device *to_keene_dev(struct v4l2_device *v4l2_dev) 79 + { 80 + return container_of(v4l2_dev, struct keene_device, v4l2_dev); 81 + } 82 + 83 + /* Set frequency (if non-0), PA, mute and turn on/off the FM transmitter. */ 84 + static int keene_cmd_main(struct keene_device *radio, unsigned freq, bool play) 85 + { 86 + unsigned short freq_send = freq ? (freq - 76 * 16000) / 800 : 0; 87 + int ret; 88 + 89 + radio->buffer[0] = 0x00; 90 + radio->buffer[1] = 0x50; 91 + radio->buffer[2] = (freq_send >> 8) & 0xff; 92 + radio->buffer[3] = freq_send & 0xff; 93 + radio->buffer[4] = radio->pa; 94 + /* If bit 4 is set, then tune to the frequency. 95 + If bit 3 is set, then unmute; if bit 2 is set, then mute. 96 + If bit 1 is set, then enter idle mode; if bit 0 is set, 97 + then enter transit mode. 98 + */ 99 + radio->buffer[5] = (radio->muted ? 4 : 8) | (play ? 1 : 2) | 100 + (freq ? 0x10 : 0); 101 + radio->buffer[6] = 0x00; 102 + radio->buffer[7] = 0x00; 103 + 104 + ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0), 105 + 9, 0x21, 0x200, 2, radio->buffer, BUFFER_LENGTH, USB_TIMEOUT); 106 + 107 + if (ret < 0) { 108 + dev_warn(&radio->vdev.dev, "%s failed (%d)\n", __func__, ret); 109 + return ret; 110 + } 111 + if (freq) 112 + radio->curfreq = freq; 113 + return 0; 114 + } 115 + 116 + /* Set TX, stereo and preemphasis mode (50 us vs 75 us). */ 117 + static int keene_cmd_set(struct keene_device *radio) 118 + { 119 + int ret; 120 + 121 + radio->buffer[0] = 0x00; 122 + radio->buffer[1] = 0x51; 123 + radio->buffer[2] = radio->tx; 124 + /* If bit 0 is set, then transmit mono, otherwise stereo. 125 + If bit 2 is set, then enable 75 us preemphasis, otherwise 126 + it is 50 us. */ 127 + radio->buffer[3] = (!radio->stereo) | (radio->preemph_75_us ? 4 : 0); 128 + radio->buffer[4] = 0x00; 129 + radio->buffer[5] = 0x00; 130 + radio->buffer[6] = 0x00; 131 + radio->buffer[7] = 0x00; 132 + 133 + ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0), 134 + 9, 0x21, 0x200, 2, radio->buffer, BUFFER_LENGTH, USB_TIMEOUT); 135 + 136 + if (ret < 0) { 137 + dev_warn(&radio->vdev.dev, "%s failed (%d)\n", __func__, ret); 138 + return ret; 139 + } 140 + return 0; 141 + } 142 + 143 + /* Handle unplugging the device. 144 + * We call video_unregister_device in any case. 145 + * The last function called in this procedure is 146 + * usb_keene_device_release. 147 + */ 148 + static void usb_keene_disconnect(struct usb_interface *intf) 149 + { 150 + struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf)); 151 + 152 + v4l2_device_get(&radio->v4l2_dev); 153 + mutex_lock(&radio->lock); 154 + usb_set_intfdata(intf, NULL); 155 + video_unregister_device(&radio->vdev); 156 + v4l2_device_disconnect(&radio->v4l2_dev); 157 + mutex_unlock(&radio->lock); 158 + v4l2_device_put(&radio->v4l2_dev); 159 + } 160 + 161 + static int vidioc_querycap(struct file *file, void *priv, 162 + struct v4l2_capability *v) 163 + { 164 + struct keene_device *radio = video_drvdata(file); 165 + 166 + strlcpy(v->driver, "radio-keene", sizeof(v->driver)); 167 + strlcpy(v->card, "Keene FM Transmitter", sizeof(v->card)); 168 + usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info)); 169 + v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_MODULATOR; 170 + v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS; 171 + return 0; 172 + } 173 + 174 + static int vidioc_g_modulator(struct file *file, void *priv, 175 + struct v4l2_modulator *v) 176 + { 177 + struct keene_device *radio = video_drvdata(file); 178 + 179 + if (v->index > 0) 180 + return -EINVAL; 181 + 182 + strlcpy(v->name, "FM", sizeof(v->name)); 183 + v->rangelow = FREQ_MIN * FREQ_MUL; 184 + v->rangehigh = FREQ_MAX * FREQ_MUL; 185 + v->txsubchans = radio->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; 186 + v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 187 + return 0; 188 + } 189 + 190 + static int vidioc_s_modulator(struct file *file, void *priv, 191 + struct v4l2_modulator *v) 192 + { 193 + struct keene_device *radio = video_drvdata(file); 194 + 195 + if (v->index > 0) 196 + return -EINVAL; 197 + 198 + radio->stereo = (v->txsubchans == V4L2_TUNER_SUB_STEREO); 199 + return keene_cmd_set(radio); 200 + } 201 + 202 + static int vidioc_s_frequency(struct file *file, void *priv, 203 + struct v4l2_frequency *f) 204 + { 205 + struct keene_device *radio = video_drvdata(file); 206 + 207 + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 208 + return -EINVAL; 209 + f->frequency = clamp(f->frequency, 210 + FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL); 211 + return keene_cmd_main(radio, f->frequency, true); 212 + } 213 + 214 + static int vidioc_g_frequency(struct file *file, void *priv, 215 + struct v4l2_frequency *f) 216 + { 217 + struct keene_device *radio = video_drvdata(file); 218 + 219 + if (f->tuner != 0) 220 + return -EINVAL; 221 + f->type = V4L2_TUNER_RADIO; 222 + f->frequency = radio->curfreq; 223 + return 0; 224 + } 225 + 226 + static int keene_s_ctrl(struct v4l2_ctrl *ctrl) 227 + { 228 + static const u8 db2tx[] = { 229 + /* -15, -12, -9, -6, -3, 0 dB */ 230 + 0x03, 0x13, 0x02, 0x12, 0x22, 0x32, 231 + /* 3, 6, 9, 12, 15, 18 dB */ 232 + 0x21, 0x31, 0x20, 0x30, 0x40, 0x50 233 + }; 234 + struct keene_device *radio = 235 + container_of(ctrl->handler, struct keene_device, hdl); 236 + 237 + switch (ctrl->id) { 238 + case V4L2_CID_AUDIO_MUTE: 239 + radio->muted = ctrl->val; 240 + return keene_cmd_main(radio, 0, true); 241 + 242 + case V4L2_CID_TUNE_POWER_LEVEL: 243 + /* To go from dBuV to the register value we apply the 244 + following formula: */ 245 + radio->pa = (ctrl->val - 71) * 100 / 62; 246 + return keene_cmd_main(radio, 0, true); 247 + 248 + case V4L2_CID_TUNE_PREEMPHASIS: 249 + radio->preemph_75_us = ctrl->val == V4L2_PREEMPHASIS_75_uS; 250 + return keene_cmd_set(radio); 251 + 252 + case V4L2_CID_AUDIO_COMPRESSION_GAIN: 253 + radio->tx = db2tx[(ctrl->val - ctrl->minimum) / ctrl->step]; 254 + return keene_cmd_set(radio); 255 + } 256 + return -EINVAL; 257 + } 258 + 259 + static int vidioc_subscribe_event(struct v4l2_fh *fh, 260 + struct v4l2_event_subscription *sub) 261 + { 262 + switch (sub->type) { 263 + case V4L2_EVENT_CTRL: 264 + return v4l2_event_subscribe(fh, sub, 0); 265 + default: 266 + return -EINVAL; 267 + } 268 + } 269 + 270 + 271 + /* File system interface */ 272 + static const struct v4l2_file_operations usb_keene_fops = { 273 + .owner = THIS_MODULE, 274 + .open = v4l2_fh_open, 275 + .release = v4l2_fh_release, 276 + .poll = v4l2_ctrl_poll, 277 + .unlocked_ioctl = video_ioctl2, 278 + }; 279 + 280 + static const struct v4l2_ctrl_ops keene_ctrl_ops = { 281 + .s_ctrl = keene_s_ctrl, 282 + }; 283 + 284 + static const struct v4l2_ioctl_ops usb_keene_ioctl_ops = { 285 + .vidioc_querycap = vidioc_querycap, 286 + .vidioc_g_modulator = vidioc_g_modulator, 287 + .vidioc_s_modulator = vidioc_s_modulator, 288 + .vidioc_g_frequency = vidioc_g_frequency, 289 + .vidioc_s_frequency = vidioc_s_frequency, 290 + .vidioc_log_status = v4l2_ctrl_log_status, 291 + .vidioc_subscribe_event = vidioc_subscribe_event, 292 + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 293 + }; 294 + 295 + static void usb_keene_video_device_release(struct v4l2_device *v4l2_dev) 296 + { 297 + struct keene_device *radio = to_keene_dev(v4l2_dev); 298 + 299 + /* free rest memory */ 300 + v4l2_ctrl_handler_free(&radio->hdl); 301 + kfree(radio->buffer); 302 + kfree(radio); 303 + } 304 + 305 + /* check if the device is present and register with v4l and usb if it is */ 306 + static int usb_keene_probe(struct usb_interface *intf, 307 + const struct usb_device_id *id) 308 + { 309 + struct usb_device *dev = interface_to_usbdev(intf); 310 + struct keene_device *radio; 311 + struct v4l2_ctrl_handler *hdl; 312 + int retval = 0; 313 + 314 + /* 315 + * The Keene FM transmitter USB device has the same USB ID as 316 + * the Logitech AudioHub Speaker, but it should ignore the hid. 317 + * Check if the name is that of the Keene device. 318 + * If not, then someone connected the AudioHub and we shouldn't 319 + * attempt to handle this driver. 320 + * For reference: the product name of the AudioHub is 321 + * "AudioHub Speaker". 322 + */ 323 + if (dev->product && strcmp(dev->product, "B-LINK USB Audio ")) 324 + return -ENODEV; 325 + 326 + radio = kzalloc(sizeof(struct keene_device), GFP_KERNEL); 327 + if (radio) 328 + radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); 329 + 330 + if (!radio || !radio->buffer) { 331 + dev_err(&intf->dev, "kmalloc for keene_device failed\n"); 332 + kfree(radio); 333 + retval = -ENOMEM; 334 + goto err; 335 + } 336 + 337 + hdl = &radio->hdl; 338 + v4l2_ctrl_handler_init(hdl, 4); 339 + v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_AUDIO_MUTE, 340 + 0, 1, 1, 0); 341 + v4l2_ctrl_new_std_menu(hdl, &keene_ctrl_ops, V4L2_CID_TUNE_PREEMPHASIS, 342 + V4L2_PREEMPHASIS_75_uS, 1, V4L2_PREEMPHASIS_50_uS); 343 + v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_TUNE_POWER_LEVEL, 344 + 84, 118, 1, 118); 345 + v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_AUDIO_COMPRESSION_GAIN, 346 + -15, 18, 3, 0); 347 + radio->pa = 118; 348 + radio->tx = 0x32; 349 + radio->stereo = true; 350 + radio->curfreq = 95.16 * FREQ_MUL; 351 + if (hdl->error) { 352 + retval = hdl->error; 353 + 354 + v4l2_ctrl_handler_free(hdl); 355 + goto err_v4l2; 356 + } 357 + retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev); 358 + if (retval < 0) { 359 + dev_err(&intf->dev, "couldn't register v4l2_device\n"); 360 + goto err_v4l2; 361 + } 362 + 363 + mutex_init(&radio->lock); 364 + 365 + radio->v4l2_dev.ctrl_handler = hdl; 366 + radio->v4l2_dev.release = usb_keene_video_device_release; 367 + strlcpy(radio->vdev.name, radio->v4l2_dev.name, 368 + sizeof(radio->vdev.name)); 369 + radio->vdev.v4l2_dev = &radio->v4l2_dev; 370 + radio->vdev.fops = &usb_keene_fops; 371 + radio->vdev.ioctl_ops = &usb_keene_ioctl_ops; 372 + radio->vdev.lock = &radio->lock; 373 + radio->vdev.release = video_device_release_empty; 374 + 375 + radio->usbdev = interface_to_usbdev(intf); 376 + radio->intf = intf; 377 + usb_set_intfdata(intf, &radio->v4l2_dev); 378 + 379 + video_set_drvdata(&radio->vdev, radio); 380 + set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags); 381 + 382 + retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1); 383 + if (retval < 0) { 384 + dev_err(&intf->dev, "could not register video device\n"); 385 + goto err_vdev; 386 + } 387 + v4l2_ctrl_handler_setup(hdl); 388 + dev_info(&intf->dev, "V4L2 device registered as %s\n", 389 + video_device_node_name(&radio->vdev)); 390 + return 0; 391 + 392 + err_vdev: 393 + v4l2_device_unregister(&radio->v4l2_dev); 394 + err_v4l2: 395 + kfree(radio->buffer); 396 + kfree(radio); 397 + err: 398 + return retval; 399 + } 400 + 401 + /* USB subsystem interface */ 402 + static struct usb_driver usb_keene_driver = { 403 + .name = "radio-keene", 404 + .probe = usb_keene_probe, 405 + .disconnect = usb_keene_disconnect, 406 + .id_table = usb_keene_device_table, 407 + }; 408 + 409 + static int __init keene_init(void) 410 + { 411 + int retval = usb_register(&usb_keene_driver); 412 + 413 + if (retval) 414 + pr_err(KBUILD_MODNAME 415 + ": usb_register failed. Error number %d\n", retval); 416 + 417 + return retval; 418 + } 419 + 420 + static void __exit keene_exit(void) 421 + { 422 + usb_deregister(&usb_keene_driver); 423 + } 424 + 425 + module_init(keene_init); 426 + module_exit(keene_exit); 427 +
+66 -317
drivers/media/radio/radio-maxiradio.c
··· 42 42 #include <linux/videodev2.h> 43 43 #include <linux/io.h> 44 44 #include <linux/slab.h> 45 + #include <sound/tea575x-tuner.h> 45 46 #include <media/v4l2-device.h> 46 47 #include <media/v4l2-ioctl.h> 47 - 48 - #define DRIVER_VERSION "0.7.8" 49 - 48 + #include <media/v4l2-fh.h> 49 + #include <media/v4l2-ctrls.h> 50 + #include <media/v4l2-event.h> 50 51 51 52 MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net"); 52 - MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio."); 53 + MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000."); 53 54 MODULE_LICENSE("GPL"); 54 - MODULE_VERSION(DRIVER_VERSION); 55 + MODULE_VERSION("1.0.0"); 55 56 56 57 static int radio_nr = -1; 57 - module_param(radio_nr, int, 0); 58 - 59 - static int debug; 60 - 61 - module_param(debug, int, 0644); 62 - MODULE_PARM_DESC(debug, "activates debug info"); 63 - 64 - #define dprintk(dev, num, fmt, arg...) \ 65 - v4l2_dbg(num, debug, &dev->v4l2_dev, fmt, ## arg) 66 - 67 - #ifndef PCI_VENDOR_ID_GUILLEMOT 68 - #define PCI_VENDOR_ID_GUILLEMOT 0x5046 69 - #endif 70 - 71 - #ifndef PCI_DEVICE_ID_GUILLEMOT 72 - #define PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO 0x1001 73 - #endif 74 - 58 + module_param(radio_nr, int, 0644); 59 + MODULE_PARM_DESC(radio_nr, "Radio device number"); 75 60 76 61 /* TEA5757 pin mappings */ 77 62 static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16; 78 63 79 - #define FREQ_LO (87 * 16000) 80 - #define FREQ_HI (108 * 16000) 64 + static atomic_t maxiradio_instance = ATOMIC_INIT(0); 81 65 82 - #define FREQ_IF 171200 /* 10.7*16000 */ 83 - #define FREQ_STEP 200 /* 12.5*16 */ 84 - 85 - /* (x==fmhz*16*1000) -> bits */ 86 - #define FREQ2BITS(x) \ 87 - ((((unsigned int)(x) + FREQ_IF + (FREQ_STEP << 1)) / (FREQ_STEP << 2)) << 2) 88 - 89 - #define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF) 90 - 66 + #define PCI_VENDOR_ID_GUILLEMOT 0x5046 67 + #define PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO 0x1001 91 68 92 69 struct maxiradio 93 70 { 71 + struct snd_tea575x tea; 94 72 struct v4l2_device v4l2_dev; 95 - struct video_device vdev; 96 73 struct pci_dev *pdev; 97 74 98 75 u16 io; /* base of radio io */ 99 - u16 muted; /* VIDEO_AUDIO_MUTE */ 100 - u16 stereo; /* VIDEO_TUNER_STEREO_ON */ 101 - u16 tuned; /* signal strength (0 or 0xffff) */ 102 - 103 - unsigned long freq; 104 - 105 - struct mutex lock; 106 76 }; 107 77 108 78 static inline struct maxiradio *to_maxiradio(struct v4l2_device *v4l2_dev) ··· 80 110 return container_of(v4l2_dev, struct maxiradio, v4l2_dev); 81 111 } 82 112 83 - static void outbit(unsigned long bit, u16 io) 113 + static void maxiradio_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) 84 114 { 85 - int val = power | wren | (bit ? data : 0); 115 + struct maxiradio *dev = tea->private_data; 116 + u8 bits = 0; 86 117 87 - outb(val, io); 88 - udelay(4); 89 - outb(val | clk, io); 90 - udelay(4); 91 - outb(val, io); 92 - udelay(4); 118 + bits |= (pins & TEA575X_DATA) ? data : 0; 119 + bits |= (pins & TEA575X_CLK) ? clk : 0; 120 + bits |= (pins & TEA575X_WREN) ? wren : 0; 121 + bits |= power; 122 + 123 + outb(bits, dev->io); 93 124 } 94 125 95 - static void turn_power(struct maxiradio *dev, int p) 126 + /* Note: this card cannot read out the data of the shift registers, 127 + only the mono/stereo pin works. */ 128 + static u8 maxiradio_tea575x_get_pins(struct snd_tea575x *tea) 96 129 { 97 - if (p != 0) { 98 - dprintk(dev, 1, "Radio powered on\n"); 99 - outb(power, dev->io); 100 - } else { 101 - dprintk(dev, 1, "Radio powered off\n"); 102 - outb(0, dev->io); 103 - } 130 + struct maxiradio *dev = tea->private_data; 131 + u8 bits = inb(dev->io); 132 + 133 + return ((bits & data) ? TEA575X_DATA : 0) | 134 + ((bits & mo_st) ? TEA575X_MOST : 0); 104 135 } 105 136 106 - static void set_freq(struct maxiradio *dev, u32 freq) 137 + static void maxiradio_tea575x_set_direction(struct snd_tea575x *tea, bool output) 107 138 { 108 - unsigned long int si; 109 - int bl; 110 - int io = dev->io; 111 - int val = FREQ2BITS(freq); 112 - 113 - /* TEA5757 shift register bits (see pdf) */ 114 - 115 - outbit(0, io); /* 24 search */ 116 - outbit(1, io); /* 23 search up/down */ 117 - 118 - outbit(0, io); /* 22 stereo/mono */ 119 - 120 - outbit(0, io); /* 21 band */ 121 - outbit(0, io); /* 20 band (only 00=FM works I think) */ 122 - 123 - outbit(0, io); /* 19 port ? */ 124 - outbit(0, io); /* 18 port ? */ 125 - 126 - outbit(0, io); /* 17 search level */ 127 - outbit(0, io); /* 16 search level */ 128 - 129 - si = 0x8000; 130 - for (bl = 1; bl <= 16; bl++) { 131 - outbit(val & si, io); 132 - si >>= 1; 133 - } 134 - 135 - dprintk(dev, 1, "Radio freq set to %d.%02d MHz\n", 136 - freq / 16000, 137 - freq % 16000 * 100 / 16000); 138 - 139 - turn_power(dev, 1); 140 139 } 141 140 142 - static int get_stereo(u16 io) 143 - { 144 - outb(power,io); 145 - udelay(4); 146 - 147 - return !(inb(io) & mo_st); 148 - } 149 - 150 - static int get_tune(u16 io) 151 - { 152 - outb(power+clk,io); 153 - udelay(4); 154 - 155 - return !(inb(io) & mo_st); 156 - } 157 - 158 - 159 - static int vidioc_querycap(struct file *file, void *priv, 160 - struct v4l2_capability *v) 161 - { 162 - struct maxiradio *dev = video_drvdata(file); 163 - 164 - strlcpy(v->driver, "radio-maxiradio", sizeof(v->driver)); 165 - strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof(v->card)); 166 - snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev)); 167 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 168 - return 0; 169 - } 170 - 171 - static int vidioc_g_tuner(struct file *file, void *priv, 172 - struct v4l2_tuner *v) 173 - { 174 - struct maxiradio *dev = video_drvdata(file); 175 - 176 - if (v->index > 0) 177 - return -EINVAL; 178 - 179 - mutex_lock(&dev->lock); 180 - strlcpy(v->name, "FM", sizeof(v->name)); 181 - v->type = V4L2_TUNER_RADIO; 182 - v->rangelow = FREQ_LO; 183 - v->rangehigh = FREQ_HI; 184 - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 185 - v->capability = V4L2_TUNER_CAP_LOW; 186 - if (get_stereo(dev->io)) 187 - v->audmode = V4L2_TUNER_MODE_STEREO; 188 - else 189 - v->audmode = V4L2_TUNER_MODE_MONO; 190 - v->signal = 0xffff * get_tune(dev->io); 191 - mutex_unlock(&dev->lock); 192 - 193 - return 0; 194 - } 195 - 196 - static int vidioc_s_tuner(struct file *file, void *priv, 197 - struct v4l2_tuner *v) 198 - { 199 - return v->index ? -EINVAL : 0; 200 - } 201 - 202 - static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 203 - { 204 - *i = 0; 205 - return 0; 206 - } 207 - 208 - static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 209 - { 210 - return i ? -EINVAL : 0; 211 - } 212 - 213 - static int vidioc_g_audio(struct file *file, void *priv, 214 - struct v4l2_audio *a) 215 - { 216 - a->index = 0; 217 - strlcpy(a->name, "Radio", sizeof(a->name)); 218 - a->capability = V4L2_AUDCAP_STEREO; 219 - return 0; 220 - } 221 - 222 - 223 - static int vidioc_s_audio(struct file *file, void *priv, 224 - struct v4l2_audio *a) 225 - { 226 - return a->index ? -EINVAL : 0; 227 - } 228 - 229 - static int vidioc_s_frequency(struct file *file, void *priv, 230 - struct v4l2_frequency *f) 231 - { 232 - struct maxiradio *dev = video_drvdata(file); 233 - 234 - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 235 - return -EINVAL; 236 - if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) { 237 - dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n", 238 - f->frequency / 16000, 239 - f->frequency % 16000 * 100 / 16000, 240 - FREQ_LO / 16000, FREQ_HI / 16000); 241 - 242 - return -EINVAL; 243 - } 244 - 245 - mutex_lock(&dev->lock); 246 - dev->freq = f->frequency; 247 - set_freq(dev, dev->freq); 248 - msleep(125); 249 - mutex_unlock(&dev->lock); 250 - 251 - return 0; 252 - } 253 - 254 - static int vidioc_g_frequency(struct file *file, void *priv, 255 - struct v4l2_frequency *f) 256 - { 257 - struct maxiradio *dev = video_drvdata(file); 258 - 259 - if (f->tuner != 0) 260 - return -EINVAL; 261 - f->type = V4L2_TUNER_RADIO; 262 - f->frequency = dev->freq; 263 - 264 - dprintk(dev, 4, "radio freq is %d.%02d MHz", 265 - f->frequency / 16000, 266 - f->frequency % 16000 * 100 / 16000); 267 - 268 - return 0; 269 - } 270 - 271 - static int vidioc_queryctrl(struct file *file, void *priv, 272 - struct v4l2_queryctrl *qc) 273 - { 274 - switch (qc->id) { 275 - case V4L2_CID_AUDIO_MUTE: 276 - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 277 - } 278 - return -EINVAL; 279 - } 280 - 281 - static int vidioc_g_ctrl(struct file *file, void *priv, 282 - struct v4l2_control *ctrl) 283 - { 284 - struct maxiradio *dev = video_drvdata(file); 285 - 286 - switch (ctrl->id) { 287 - case V4L2_CID_AUDIO_MUTE: 288 - ctrl->value = dev->muted; 289 - return 0; 290 - } 291 - 292 - return -EINVAL; 293 - } 294 - 295 - static int vidioc_s_ctrl(struct file *file, void *priv, 296 - struct v4l2_control *ctrl) 297 - { 298 - struct maxiradio *dev = video_drvdata(file); 299 - 300 - switch (ctrl->id) { 301 - case V4L2_CID_AUDIO_MUTE: 302 - mutex_lock(&dev->lock); 303 - dev->muted = ctrl->value; 304 - if (dev->muted) 305 - turn_power(dev, 0); 306 - else 307 - set_freq(dev, dev->freq); 308 - mutex_unlock(&dev->lock); 309 - return 0; 310 - } 311 - 312 - return -EINVAL; 313 - } 314 - 315 - static const struct v4l2_file_operations maxiradio_fops = { 316 - .owner = THIS_MODULE, 317 - .unlocked_ioctl = video_ioctl2, 141 + static struct snd_tea575x_ops maxiradio_tea_ops = { 142 + .set_pins = maxiradio_tea575x_set_pins, 143 + .get_pins = maxiradio_tea575x_get_pins, 144 + .set_direction = maxiradio_tea575x_set_direction, 318 145 }; 319 146 320 - static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { 321 - .vidioc_querycap = vidioc_querycap, 322 - .vidioc_g_tuner = vidioc_g_tuner, 323 - .vidioc_s_tuner = vidioc_s_tuner, 324 - .vidioc_g_audio = vidioc_g_audio, 325 - .vidioc_s_audio = vidioc_s_audio, 326 - .vidioc_g_input = vidioc_g_input, 327 - .vidioc_s_input = vidioc_s_input, 328 - .vidioc_g_frequency = vidioc_g_frequency, 329 - .vidioc_s_frequency = vidioc_s_frequency, 330 - .vidioc_queryctrl = vidioc_queryctrl, 331 - .vidioc_g_ctrl = vidioc_g_ctrl, 332 - .vidioc_s_ctrl = vidioc_s_ctrl, 333 - }; 334 - 335 - static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 147 + static int __devinit maxiradio_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 336 148 { 337 149 struct maxiradio *dev; 338 150 struct v4l2_device *v4l2_dev; ··· 127 375 } 128 376 129 377 v4l2_dev = &dev->v4l2_dev; 130 - mutex_init(&dev->lock); 131 - dev->pdev = pdev; 132 - dev->muted = 1; 133 - dev->freq = FREQ_LO; 134 - 135 - strlcpy(v4l2_dev->name, "maxiradio", sizeof(v4l2_dev->name)); 378 + v4l2_device_set_name(v4l2_dev, "maxiradio", &maxiradio_instance); 136 379 137 380 retval = v4l2_device_register(&pdev->dev, v4l2_dev); 138 381 if (retval < 0) { 139 382 v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 140 383 goto errfr; 141 384 } 385 + dev->tea.private_data = dev; 386 + dev->tea.ops = &maxiradio_tea_ops; 387 + /* The data pin cannot be read. This may be a hardware limitation, or 388 + we just don't know how to read it. */ 389 + dev->tea.cannot_read_data = true; 390 + dev->tea.v4l2_dev = v4l2_dev; 391 + dev->tea.radio_nr = radio_nr; 392 + strlcpy(dev->tea.card, "Maxi Radio FM2000", sizeof(dev->tea.card)); 393 + snprintf(dev->tea.bus_info, sizeof(dev->tea.bus_info), 394 + "PCI:%s", pci_name(pdev)); 395 + 396 + retval = -ENODEV; 142 397 143 398 if (!request_region(pci_resource_start(pdev, 0), 144 - pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) { 145 - v4l2_err(v4l2_dev, "can't reserve I/O ports\n"); 146 - goto err_out; 399 + pci_resource_len(pdev, 0), v4l2_dev->name)) { 400 + dev_err(&pdev->dev, "can't reserve I/O ports\n"); 401 + goto err_hdl; 147 402 } 148 403 149 404 if (pci_enable_device(pdev)) 150 405 goto err_out_free_region; 151 406 152 407 dev->io = pci_resource_start(pdev, 0); 153 - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); 154 - dev->vdev.v4l2_dev = v4l2_dev; 155 - dev->vdev.fops = &maxiradio_fops; 156 - dev->vdev.ioctl_ops = &maxiradio_ioctl_ops; 157 - dev->vdev.release = video_device_release_empty; 158 - video_set_drvdata(&dev->vdev, dev); 159 - 160 - if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 161 - v4l2_err(v4l2_dev, "can't register device!"); 408 + if (snd_tea575x_init(&dev->tea)) { 409 + printk(KERN_ERR "radio-maxiradio: Unable to detect TEA575x tuner\n"); 162 410 goto err_out_free_region; 163 411 } 164 - 165 - v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); 166 - 167 - v4l2_info(v4l2_dev, "found Guillemot MAXI Radio device (io = 0x%x)\n", 168 - dev->io); 169 412 return 0; 170 413 171 414 err_out_free_region: 172 415 release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); 173 - err_out: 416 + err_hdl: 174 417 v4l2_device_unregister(v4l2_dev); 175 418 errfr: 176 419 kfree(dev); 177 - return -ENODEV; 420 + return retval; 178 421 } 179 422 180 - static void __devexit maxiradio_remove_one(struct pci_dev *pdev) 423 + static void __devexit maxiradio_remove(struct pci_dev *pdev) 181 424 { 182 425 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); 183 426 struct maxiradio *dev = to_maxiradio(v4l2_dev); 184 427 185 - video_unregister_device(&dev->vdev); 186 - v4l2_device_unregister(&dev->v4l2_dev); 428 + snd_tea575x_exit(&dev->tea); 429 + /* Turn off power */ 430 + outb(0, dev->io); 431 + v4l2_device_unregister(v4l2_dev); 187 432 release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); 188 433 } 189 434 ··· 195 446 static struct pci_driver maxiradio_driver = { 196 447 .name = "radio-maxiradio", 197 448 .id_table = maxiradio_pci_tbl, 198 - .probe = maxiradio_init_one, 199 - .remove = __devexit_p(maxiradio_remove_one), 449 + .probe = maxiradio_probe, 450 + .remove = __devexit_p(maxiradio_remove), 200 451 }; 201 452 202 - static int __init maxiradio_radio_init(void) 453 + static int __init maxiradio_init(void) 203 454 { 204 455 return pci_register_driver(&maxiradio_driver); 205 456 } 206 457 207 - static void __exit maxiradio_radio_exit(void) 458 + static void __exit maxiradio_exit(void) 208 459 { 209 460 pci_unregister_driver(&maxiradio_driver); 210 461 } 211 462 212 - module_init(maxiradio_radio_init); 213 - module_exit(maxiradio_radio_exit); 463 + module_init(maxiradio_init); 464 + module_exit(maxiradio_exit);
+69 -271
drivers/media/radio/radio-rtrack2.c
··· 1 - /* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff 1 + /* 2 + * RadioTrack II driver 3 + * Copyright 1998 Ben Pfaff 2 4 * 3 5 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood 4 6 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> 5 7 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 6 8 * 7 - * TODO: Allow for more than one of these foolish entities :-) 8 - * 9 + * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> 9 10 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 10 11 */ 11 12 ··· 19 18 #include <linux/io.h> /* outb, outb_p */ 20 19 #include <media/v4l2-device.h> 21 20 #include <media/v4l2-ioctl.h> 21 + #include "radio-isa.h" 22 22 23 23 MODULE_AUTHOR("Ben Pfaff"); 24 24 MODULE_DESCRIPTION("A driver for the RadioTrack II radio card."); 25 25 MODULE_LICENSE("GPL"); 26 - MODULE_VERSION("0.0.3"); 26 + MODULE_VERSION("0.1.99"); 27 27 28 28 #ifndef CONFIG_RADIO_RTRACK2_PORT 29 29 #define CONFIG_RADIO_RTRACK2_PORT -1 30 30 #endif 31 31 32 - static int io = CONFIG_RADIO_RTRACK2_PORT; 33 - static int radio_nr = -1; 32 + #define RTRACK2_MAX 2 34 33 35 - module_param(io, int, 0); 36 - MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)"); 37 - module_param(radio_nr, int, 0); 34 + static int io[RTRACK2_MAX] = { [0] = CONFIG_RADIO_RTRACK2_PORT, 35 + [1 ... (RTRACK2_MAX - 1)] = -1 }; 36 + static int radio_nr[RTRACK2_MAX] = { [0 ... (RTRACK2_MAX - 1)] = -1 }; 38 37 39 - struct rtrack2 38 + module_param_array(io, int, NULL, 0444); 39 + MODULE_PARM_DESC(io, "I/O addresses of the RadioTrack card (0x20f or 0x30f)"); 40 + module_param_array(radio_nr, int, NULL, 0444); 41 + MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 42 + 43 + static struct radio_isa_card *rtrack2_alloc(void) 40 44 { 41 - struct v4l2_device v4l2_dev; 42 - struct video_device vdev; 43 - int io; 44 - unsigned long curfreq; 45 - int muted; 46 - struct mutex lock; 47 - }; 48 - 49 - static struct rtrack2 rtrack2_card; 50 - 51 - 52 - /* local things */ 53 - 54 - static void rt_mute(struct rtrack2 *dev) 55 - { 56 - if (dev->muted) 57 - return; 58 - mutex_lock(&dev->lock); 59 - outb(1, dev->io); 60 - mutex_unlock(&dev->lock); 61 - dev->muted = 1; 45 + return kzalloc(sizeof(struct radio_isa_card), GFP_KERNEL); 62 46 } 63 47 64 - static void rt_unmute(struct rtrack2 *dev) 48 + static void zero(struct radio_isa_card *isa) 65 49 { 66 - if(dev->muted == 0) 67 - return; 68 - mutex_lock(&dev->lock); 69 - outb(0, dev->io); 70 - mutex_unlock(&dev->lock); 71 - dev->muted = 0; 50 + outb_p(1, isa->io); 51 + outb_p(3, isa->io); 52 + outb_p(1, isa->io); 72 53 } 73 54 74 - static void zero(struct rtrack2 *dev) 55 + static void one(struct radio_isa_card *isa) 75 56 { 76 - outb_p(1, dev->io); 77 - outb_p(3, dev->io); 78 - outb_p(1, dev->io); 57 + outb_p(5, isa->io); 58 + outb_p(7, isa->io); 59 + outb_p(5, isa->io); 79 60 } 80 61 81 - static void one(struct rtrack2 *dev) 82 - { 83 - outb_p(5, dev->io); 84 - outb_p(7, dev->io); 85 - outb_p(5, dev->io); 86 - } 87 - 88 - static int rt_setfreq(struct rtrack2 *dev, unsigned long freq) 62 + static int rtrack2_s_frequency(struct radio_isa_card *isa, u32 freq) 89 63 { 90 64 int i; 91 65 92 - mutex_lock(&dev->lock); 93 - dev->curfreq = freq; 94 66 freq = freq / 200 + 856; 95 67 96 - outb_p(0xc8, dev->io); 97 - outb_p(0xc9, dev->io); 98 - outb_p(0xc9, dev->io); 68 + outb_p(0xc8, isa->io); 69 + outb_p(0xc9, isa->io); 70 + outb_p(0xc9, isa->io); 99 71 100 72 for (i = 0; i < 10; i++) 101 - zero(dev); 73 + zero(isa); 102 74 103 75 for (i = 14; i >= 0; i--) 104 76 if (freq & (1 << i)) 105 - one(dev); 77 + one(isa); 106 78 else 107 - zero(dev); 79 + zero(isa); 108 80 109 - outb_p(0xc8, dev->io); 110 - if (!dev->muted) 111 - outb_p(0, dev->io); 112 - 113 - mutex_unlock(&dev->lock); 81 + outb_p(0xc8, isa->io); 82 + if (!v4l2_ctrl_g_ctrl(isa->mute)) 83 + outb_p(0, isa->io); 114 84 return 0; 115 85 } 116 86 117 - static int vidioc_querycap(struct file *file, void *priv, 118 - struct v4l2_capability *v) 87 + static u32 rtrack2_g_signal(struct radio_isa_card *isa) 119 88 { 120 - strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver)); 121 - strlcpy(v->card, "RadioTrack II", sizeof(v->card)); 122 - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 123 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 89 + /* bit set = no signal present */ 90 + return (inb(isa->io) & 2) ? 0 : 0xffff; 91 + } 92 + 93 + static int rtrack2_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) 94 + { 95 + outb(mute, isa->io); 124 96 return 0; 125 97 } 126 98 127 - static int vidioc_s_tuner(struct file *file, void *priv, 128 - struct v4l2_tuner *v) 129 - { 130 - return v->index ? -EINVAL : 0; 131 - } 132 - 133 - static int rt_getsigstr(struct rtrack2 *dev) 134 - { 135 - int sig = 1; 136 - 137 - mutex_lock(&dev->lock); 138 - if (inb(dev->io) & 2) /* bit set = no signal present */ 139 - sig = 0; 140 - mutex_unlock(&dev->lock); 141 - return sig; 142 - } 143 - 144 - static int vidioc_g_tuner(struct file *file, void *priv, 145 - struct v4l2_tuner *v) 146 - { 147 - struct rtrack2 *rt = video_drvdata(file); 148 - 149 - if (v->index > 0) 150 - return -EINVAL; 151 - 152 - strlcpy(v->name, "FM", sizeof(v->name)); 153 - v->type = V4L2_TUNER_RADIO; 154 - v->rangelow = 88 * 16000; 155 - v->rangehigh = 108 * 16000; 156 - v->rxsubchans = V4L2_TUNER_SUB_MONO; 157 - v->capability = V4L2_TUNER_CAP_LOW; 158 - v->audmode = V4L2_TUNER_MODE_MONO; 159 - v->signal = 0xFFFF * rt_getsigstr(rt); 160 - return 0; 161 - } 162 - 163 - static int vidioc_s_frequency(struct file *file, void *priv, 164 - struct v4l2_frequency *f) 165 - { 166 - struct rtrack2 *rt = video_drvdata(file); 167 - 168 - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 169 - return -EINVAL; 170 - rt_setfreq(rt, f->frequency); 171 - return 0; 172 - } 173 - 174 - static int vidioc_g_frequency(struct file *file, void *priv, 175 - struct v4l2_frequency *f) 176 - { 177 - struct rtrack2 *rt = video_drvdata(file); 178 - 179 - if (f->tuner != 0) 180 - return -EINVAL; 181 - f->type = V4L2_TUNER_RADIO; 182 - f->frequency = rt->curfreq; 183 - return 0; 184 - } 185 - 186 - static int vidioc_queryctrl(struct file *file, void *priv, 187 - struct v4l2_queryctrl *qc) 188 - { 189 - switch (qc->id) { 190 - case V4L2_CID_AUDIO_MUTE: 191 - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 192 - case V4L2_CID_AUDIO_VOLUME: 193 - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535); 194 - } 195 - return -EINVAL; 196 - } 197 - 198 - static int vidioc_g_ctrl(struct file *file, void *priv, 199 - struct v4l2_control *ctrl) 200 - { 201 - struct rtrack2 *rt = video_drvdata(file); 202 - 203 - switch (ctrl->id) { 204 - case V4L2_CID_AUDIO_MUTE: 205 - ctrl->value = rt->muted; 206 - return 0; 207 - case V4L2_CID_AUDIO_VOLUME: 208 - if (rt->muted) 209 - ctrl->value = 0; 210 - else 211 - ctrl->value = 65535; 212 - return 0; 213 - } 214 - return -EINVAL; 215 - } 216 - 217 - static int vidioc_s_ctrl(struct file *file, void *priv, 218 - struct v4l2_control *ctrl) 219 - { 220 - struct rtrack2 *rt = video_drvdata(file); 221 - 222 - switch (ctrl->id) { 223 - case V4L2_CID_AUDIO_MUTE: 224 - if (ctrl->value) 225 - rt_mute(rt); 226 - else 227 - rt_unmute(rt); 228 - return 0; 229 - case V4L2_CID_AUDIO_VOLUME: 230 - if (ctrl->value) 231 - rt_unmute(rt); 232 - else 233 - rt_mute(rt); 234 - return 0; 235 - } 236 - return -EINVAL; 237 - } 238 - 239 - static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 240 - { 241 - *i = 0; 242 - return 0; 243 - } 244 - 245 - static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 246 - { 247 - return i ? -EINVAL : 0; 248 - } 249 - 250 - static int vidioc_g_audio(struct file *file, void *priv, 251 - struct v4l2_audio *a) 252 - { 253 - a->index = 0; 254 - strlcpy(a->name, "Radio", sizeof(a->name)); 255 - a->capability = V4L2_AUDCAP_STEREO; 256 - return 0; 257 - } 258 - 259 - static int vidioc_s_audio(struct file *file, void *priv, 260 - struct v4l2_audio *a) 261 - { 262 - return a->index ? -EINVAL : 0; 263 - } 264 - 265 - static const struct v4l2_file_operations rtrack2_fops = { 266 - .owner = THIS_MODULE, 267 - .unlocked_ioctl = video_ioctl2, 99 + static const struct radio_isa_ops rtrack2_ops = { 100 + .alloc = rtrack2_alloc, 101 + .s_mute_volume = rtrack2_s_mute_volume, 102 + .s_frequency = rtrack2_s_frequency, 103 + .g_signal = rtrack2_g_signal, 268 104 }; 269 105 270 - static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { 271 - .vidioc_querycap = vidioc_querycap, 272 - .vidioc_g_tuner = vidioc_g_tuner, 273 - .vidioc_s_tuner = vidioc_s_tuner, 274 - .vidioc_g_frequency = vidioc_g_frequency, 275 - .vidioc_s_frequency = vidioc_s_frequency, 276 - .vidioc_queryctrl = vidioc_queryctrl, 277 - .vidioc_g_ctrl = vidioc_g_ctrl, 278 - .vidioc_s_ctrl = vidioc_s_ctrl, 279 - .vidioc_g_audio = vidioc_g_audio, 280 - .vidioc_s_audio = vidioc_s_audio, 281 - .vidioc_g_input = vidioc_g_input, 282 - .vidioc_s_input = vidioc_s_input, 106 + static const int rtrack2_ioports[] = { 0x20f, 0x30f }; 107 + 108 + static struct radio_isa_driver rtrack2_driver = { 109 + .driver = { 110 + .match = radio_isa_match, 111 + .probe = radio_isa_probe, 112 + .remove = radio_isa_remove, 113 + .driver = { 114 + .name = "radio-rtrack2", 115 + }, 116 + }, 117 + .io_params = io, 118 + .radio_nr_params = radio_nr, 119 + .io_ports = rtrack2_ioports, 120 + .num_of_io_ports = ARRAY_SIZE(rtrack2_ioports), 121 + .region_size = 4, 122 + .card = "AIMSlab RadioTrack II", 123 + .ops = &rtrack2_ops, 124 + .has_stereo = true, 283 125 }; 284 126 285 127 static int __init rtrack2_init(void) 286 128 { 287 - struct rtrack2 *dev = &rtrack2_card; 288 - struct v4l2_device *v4l2_dev = &dev->v4l2_dev; 289 - int res; 290 - 291 - strlcpy(v4l2_dev->name, "rtrack2", sizeof(v4l2_dev->name)); 292 - dev->io = io; 293 - if (dev->io == -1) { 294 - v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or io=0x30c\n"); 295 - return -EINVAL; 296 - } 297 - if (!request_region(dev->io, 4, "rtrack2")) { 298 - v4l2_err(v4l2_dev, "port 0x%x already in use\n", dev->io); 299 - return -EBUSY; 300 - } 301 - 302 - res = v4l2_device_register(NULL, v4l2_dev); 303 - if (res < 0) { 304 - release_region(dev->io, 4); 305 - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 306 - return res; 307 - } 308 - 309 - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); 310 - dev->vdev.v4l2_dev = v4l2_dev; 311 - dev->vdev.fops = &rtrack2_fops; 312 - dev->vdev.ioctl_ops = &rtrack2_ioctl_ops; 313 - dev->vdev.release = video_device_release_empty; 314 - video_set_drvdata(&dev->vdev, dev); 315 - 316 - /* mute card - prevents noisy bootups */ 317 - outb(1, dev->io); 318 - dev->muted = 1; 319 - 320 - mutex_init(&dev->lock); 321 - if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 322 - v4l2_device_unregister(v4l2_dev); 323 - release_region(dev->io, 4); 324 - return -EINVAL; 325 - } 326 - 327 - v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); 328 - 329 - return 0; 129 + return isa_register_driver(&rtrack2_driver.driver, RTRACK2_MAX); 330 130 } 331 131 332 132 static void __exit rtrack2_exit(void) 333 133 { 334 - struct rtrack2 *dev = &rtrack2_card; 335 - 336 - video_unregister_device(&dev->vdev); 337 - v4l2_device_unregister(&dev->v4l2_dev); 338 - release_region(dev->io, 4); 134 + isa_unregister_driver(&rtrack2_driver.driver); 339 135 } 340 136 341 137 module_init(rtrack2_init);
+54 -7
drivers/media/radio/radio-sf16fmr2.c
··· 9 9 #include <linux/delay.h> 10 10 #include <linux/module.h> /* Modules */ 11 11 #include <linux/init.h> /* Initdata */ 12 + #include <linux/slab.h> 12 13 #include <linux/ioport.h> /* request_region */ 13 14 #include <linux/io.h> /* outb, outb_p */ 15 + #include <linux/isa.h> 14 16 #include <sound/tea575x-tuner.h> 15 17 16 18 MODULE_AUTHOR("Ondrej Zary"); 17 19 MODULE_DESCRIPTION("MediaForte SF16-FMR2 FM radio card driver"); 18 20 MODULE_LICENSE("GPL"); 19 21 22 + static int radio_nr = -1; 23 + module_param(radio_nr, int, 0444); 24 + MODULE_PARM_DESC(radio_nr, "Radio device number"); 25 + 20 26 struct fmr2 { 21 27 int io; 28 + struct v4l2_device v4l2_dev; 22 29 struct snd_tea575x tea; 23 30 struct v4l2_ctrl *volume; 24 31 struct v4l2_ctrl *balance; ··· 33 26 34 27 /* the port is hardwired so no need to support multiple cards */ 35 28 #define FMR2_PORT 0x384 36 - static struct fmr2 fmr2_card; 37 29 38 30 /* TEA575x tuner pins */ 39 31 #define STR_DATA (1 << 0) ··· 186 180 return 0; 187 181 } 188 182 189 - static int __init fmr2_init(void) 183 + static int __devinit fmr2_probe(struct device *pdev, unsigned int dev) 190 184 { 191 - struct fmr2 *fmr2 = &fmr2_card; 185 + struct fmr2 *fmr2; 186 + int err; 192 187 188 + fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL); 189 + if (fmr2 == NULL) 190 + return -ENOMEM; 191 + 192 + strlcpy(fmr2->v4l2_dev.name, dev_name(pdev), 193 + sizeof(fmr2->v4l2_dev.name)); 193 194 fmr2->io = FMR2_PORT; 194 195 195 - if (!request_region(fmr2->io, 2, "SF16-FMR2")) { 196 + if (!request_region(fmr2->io, 2, fmr2->v4l2_dev.name)) { 196 197 printk(KERN_ERR "radio-sf16fmr2: I/O port 0x%x already in use\n", fmr2->io); 198 + kfree(fmr2); 197 199 return -EBUSY; 198 200 } 199 201 202 + dev_set_drvdata(pdev, fmr2); 203 + err = v4l2_device_register(pdev, &fmr2->v4l2_dev); 204 + if (err < 0) { 205 + v4l2_err(&fmr2->v4l2_dev, "Could not register v4l2_device\n"); 206 + release_region(fmr2->io, 2); 207 + kfree(fmr2); 208 + return err; 209 + } 210 + fmr2->tea.v4l2_dev = &fmr2->v4l2_dev; 200 211 fmr2->tea.private_data = fmr2; 212 + fmr2->tea.radio_nr = radio_nr; 201 213 fmr2->tea.ops = &fmr2_tea_ops; 202 214 fmr2->tea.ext_init = fmr2_tea_ext_init; 203 215 strlcpy(fmr2->tea.card, "SF16-FMR2", sizeof(fmr2->tea.card)); 204 - strcpy(fmr2->tea.bus_info, "ISA"); 216 + snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "ISA:%s", 217 + fmr2->v4l2_dev.name); 205 218 206 219 if (snd_tea575x_init(&fmr2->tea)) { 207 220 printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n"); 208 221 release_region(fmr2->io, 2); 222 + kfree(fmr2); 209 223 return -ENODEV; 210 224 } 211 225 ··· 233 207 return 0; 234 208 } 235 209 236 - static void __exit fmr2_exit(void) 210 + static int __exit fmr2_remove(struct device *pdev, unsigned int dev) 237 211 { 238 - struct fmr2 *fmr2 = &fmr2_card; 212 + struct fmr2 *fmr2 = dev_get_drvdata(pdev); 239 213 240 214 snd_tea575x_exit(&fmr2->tea); 241 215 release_region(fmr2->io, 2); 216 + v4l2_device_unregister(&fmr2->v4l2_dev); 217 + kfree(fmr2); 218 + return 0; 219 + } 220 + 221 + struct isa_driver fmr2_driver = { 222 + .probe = fmr2_probe, 223 + .remove = fmr2_remove, 224 + .driver = { 225 + .name = "radio-sf16fmr2", 226 + }, 227 + }; 228 + 229 + static int __init fmr2_init(void) 230 + { 231 + return isa_register_driver(&fmr2_driver, 1); 232 + } 233 + 234 + static void __exit fmr2_exit(void) 235 + { 236 + isa_unregister_driver(&fmr2_driver); 242 237 } 243 238 244 239 module_init(fmr2_init);
+1 -18
drivers/media/radio/radio-tea5764.c
··· 575 575 .id_table = tea5764_id, 576 576 }; 577 577 578 - /* init the driver */ 579 - static int __init tea5764_init(void) 580 - { 581 - int ret = i2c_add_driver(&tea5764_i2c_driver); 582 - 583 - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ": " 584 - DRIVER_DESC "\n"); 585 - return ret; 586 - } 587 - 588 - /* cleanup the driver */ 589 - static void __exit tea5764_exit(void) 590 - { 591 - i2c_del_driver(&tea5764_i2c_driver); 592 - } 578 + module_i2c_driver(tea5764_i2c_driver); 593 579 594 580 MODULE_AUTHOR(DRIVER_AUTHOR); 595 581 MODULE_DESCRIPTION(DRIVER_DESC); ··· 586 600 MODULE_PARM_DESC(use_xtal, "Chip have a xtal connected in board"); 587 601 module_param(radio_nr, int, 0); 588 602 MODULE_PARM_DESC(radio_nr, "video4linux device number to use"); 589 - 590 - module_init(tea5764_init); 591 - module_exit(tea5764_exit);
+60 -305
drivers/media/radio/radio-terratec.c
··· 16 16 * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); 17 17 * Volume Control is done digitally 18 18 * 19 - * there is a I2C controlled RDS decoder (SAA6588) onboard, which i would like to support someday 20 - * (as soon i have understand how to get started :) 21 - * If you can help me out with that, please contact me!! 22 - * 23 - * 19 + * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> 24 20 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 25 21 */ 26 22 ··· 26 30 #include <linux/videodev2.h> /* kernel radio structs */ 27 31 #include <linux/mutex.h> 28 32 #include <linux/io.h> /* outb, outb_p */ 33 + #include <linux/slab.h> 29 34 #include <media/v4l2-device.h> 30 35 #include <media/v4l2-ioctl.h> 36 + #include "radio-isa.h" 31 37 32 - MODULE_AUTHOR("R.OFFERMANNS & others"); 38 + MODULE_AUTHOR("R. Offermans & others"); 33 39 MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card."); 34 40 MODULE_LICENSE("GPL"); 35 - MODULE_VERSION("0.0.3"); 41 + MODULE_VERSION("0.1.99"); 36 42 37 - #ifndef CONFIG_RADIO_TERRATEC_PORT 38 - #define CONFIG_RADIO_TERRATEC_PORT 0x590 39 - #endif 40 - 41 - static int io = CONFIG_RADIO_TERRATEC_PORT; 43 + /* Note: there seems to be only one possible port (0x590), but without 44 + hardware this is hard to verify. For now, this is the only one we will 45 + support. */ 46 + static int io = 0x590; 42 47 static int radio_nr = -1; 43 48 44 - module_param(io, int, 0); 45 - MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)"); 46 - module_param(radio_nr, int, 0); 47 - 48 - static struct v4l2_queryctrl radio_qctrl[] = { 49 - { 50 - .id = V4L2_CID_AUDIO_MUTE, 51 - .name = "Mute", 52 - .minimum = 0, 53 - .maximum = 1, 54 - .default_value = 1, 55 - .type = V4L2_CTRL_TYPE_BOOLEAN, 56 - },{ 57 - .id = V4L2_CID_AUDIO_VOLUME, 58 - .name = "Volume", 59 - .minimum = 0, 60 - .maximum = 0xff, 61 - .step = 1, 62 - .default_value = 0xff, 63 - .type = V4L2_CTRL_TYPE_INTEGER, 64 - } 65 - }; 49 + module_param(radio_nr, int, 0444); 50 + MODULE_PARM_DESC(radio_nr, "Radio device number"); 66 51 67 52 #define WRT_DIS 0x00 68 53 #define CLK_OFF 0x00 ··· 53 76 #define CLK_ON 0x08 54 77 #define WRT_EN 0x10 55 78 56 - struct terratec 79 + static struct radio_isa_card *terratec_alloc(void) 57 80 { 58 - struct v4l2_device v4l2_dev; 59 - struct video_device vdev; 60 - int io; 61 - int curvol; 62 - unsigned long curfreq; 63 - int muted; 64 - struct mutex lock; 65 - }; 81 + return kzalloc(sizeof(struct radio_isa_card), GFP_KERNEL); 82 + } 66 83 67 - static struct terratec terratec_card; 68 - 69 - /* local things */ 70 - 71 - static void tt_write_vol(struct terratec *tt, int volume) 84 + static int terratec_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) 72 85 { 73 86 int i; 74 87 75 - volume = volume + (volume * 32); /* change both channels */ 76 - mutex_lock(&tt->lock); 88 + if (mute) 89 + vol = 0; 90 + vol = vol + (vol * 32); /* change both channels */ 77 91 for (i = 0; i < 8; i++) { 78 - if (volume & (0x80 >> i)) 79 - outb(0x80, tt->io + 1); 92 + if (vol & (0x80 >> i)) 93 + outb(0x80, isa->io + 1); 80 94 else 81 - outb(0x00, tt->io + 1); 95 + outb(0x00, isa->io + 1); 82 96 } 83 - mutex_unlock(&tt->lock); 84 - } 85 - 86 - 87 - 88 - static void tt_mute(struct terratec *tt) 89 - { 90 - tt->muted = 1; 91 - tt_write_vol(tt, 0); 92 - } 93 - 94 - static int tt_setvol(struct terratec *tt, int vol) 95 - { 96 - if (vol == tt->curvol) { /* requested volume = current */ 97 - if (tt->muted) { /* user is unmuting the card */ 98 - tt->muted = 0; 99 - tt_write_vol(tt, vol); /* enable card */ 100 - } 101 - return 0; 102 - } 103 - 104 - if (vol == 0) { /* volume = 0 means mute the card */ 105 - tt_write_vol(tt, 0); /* "turn off card" by setting vol to 0 */ 106 - tt->curvol = vol; /* track the volume state! */ 107 - return 0; 108 - } 109 - 110 - tt->muted = 0; 111 - tt_write_vol(tt, vol); 112 - tt->curvol = vol; 113 97 return 0; 114 98 } 115 99 ··· 78 140 /* this is the worst part in this driver */ 79 141 /* many more or less strange things are going on here, but hey, it works :) */ 80 142 81 - static int tt_setfreq(struct terratec *tt, unsigned long freq1) 143 + static int terratec_s_frequency(struct radio_isa_card *isa, u32 freq) 82 144 { 83 - int freq; 84 145 int i; 85 146 int p; 86 - int temp; 147 + int temp; 87 148 long rest; 88 149 unsigned char buffer[25]; /* we have to bit shift 25 registers */ 89 150 90 - mutex_lock(&tt->lock); 91 - 92 - tt->curfreq = freq1; 93 - 94 - freq = freq1 / 160; /* convert the freq. to a nice to handle value */ 151 + freq = freq / 160; /* convert the freq. to a nice to handle value */ 95 152 memset(buffer, 0, sizeof(buffer)); 96 153 97 154 rest = freq * 10 + 10700; /* I once had understood what is going on here */ ··· 108 175 109 176 for (i = 24; i > -1; i--) { /* bit shift the values to the radiocard */ 110 177 if (buffer[i] == 1) { 111 - outb(WRT_EN | DATA, tt->io); 112 - outb(WRT_EN | DATA | CLK_ON, tt->io); 113 - outb(WRT_EN | DATA, tt->io); 178 + outb(WRT_EN | DATA, isa->io); 179 + outb(WRT_EN | DATA | CLK_ON, isa->io); 180 + outb(WRT_EN | DATA, isa->io); 114 181 } else { 115 - outb(WRT_EN | 0x00, tt->io); 116 - outb(WRT_EN | 0x00 | CLK_ON, tt->io); 182 + outb(WRT_EN | 0x00, isa->io); 183 + outb(WRT_EN | 0x00 | CLK_ON, isa->io); 117 184 } 118 185 } 119 - outb(0x00, tt->io); 120 - 121 - mutex_unlock(&tt->lock); 122 - 186 + outb(0x00, isa->io); 123 187 return 0; 124 188 } 125 189 126 - static int tt_getsigstr(struct terratec *tt) 190 + static u32 terratec_g_signal(struct radio_isa_card *isa) 127 191 { 128 - if (inb(tt->io) & 2) /* bit set = no signal present */ 129 - return 0; 130 - return 1; /* signal present */ 192 + /* bit set = no signal present */ 193 + return (inb(isa->io) & 2) ? 0 : 0xffff; 131 194 } 132 195 133 - static int vidioc_querycap(struct file *file, void *priv, 134 - struct v4l2_capability *v) 135 - { 136 - strlcpy(v->driver, "radio-terratec", sizeof(v->driver)); 137 - strlcpy(v->card, "ActiveRadio", sizeof(v->card)); 138 - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 139 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 140 - return 0; 141 - } 142 - 143 - static int vidioc_g_tuner(struct file *file, void *priv, 144 - struct v4l2_tuner *v) 145 - { 146 - struct terratec *tt = video_drvdata(file); 147 - 148 - if (v->index > 0) 149 - return -EINVAL; 150 - 151 - strlcpy(v->name, "FM", sizeof(v->name)); 152 - v->type = V4L2_TUNER_RADIO; 153 - v->rangelow = 87 * 16000; 154 - v->rangehigh = 108 * 16000; 155 - v->rxsubchans = V4L2_TUNER_SUB_MONO; 156 - v->capability = V4L2_TUNER_CAP_LOW; 157 - v->audmode = V4L2_TUNER_MODE_MONO; 158 - v->signal = 0xFFFF * tt_getsigstr(tt); 159 - return 0; 160 - } 161 - 162 - static int vidioc_s_tuner(struct file *file, void *priv, 163 - struct v4l2_tuner *v) 164 - { 165 - return v->index ? -EINVAL : 0; 166 - } 167 - 168 - static int vidioc_s_frequency(struct file *file, void *priv, 169 - struct v4l2_frequency *f) 170 - { 171 - struct terratec *tt = video_drvdata(file); 172 - 173 - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 174 - return -EINVAL; 175 - tt_setfreq(tt, f->frequency); 176 - return 0; 177 - } 178 - 179 - static int vidioc_g_frequency(struct file *file, void *priv, 180 - struct v4l2_frequency *f) 181 - { 182 - struct terratec *tt = video_drvdata(file); 183 - 184 - if (f->tuner != 0) 185 - return -EINVAL; 186 - f->type = V4L2_TUNER_RADIO; 187 - f->frequency = tt->curfreq; 188 - return 0; 189 - } 190 - 191 - static int vidioc_queryctrl(struct file *file, void *priv, 192 - struct v4l2_queryctrl *qc) 193 - { 194 - int i; 195 - 196 - for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 197 - if (qc->id && qc->id == radio_qctrl[i].id) { 198 - memcpy(qc, &(radio_qctrl[i]), sizeof(*qc)); 199 - return 0; 200 - } 201 - } 202 - return -EINVAL; 203 - } 204 - 205 - static int vidioc_g_ctrl(struct file *file, void *priv, 206 - struct v4l2_control *ctrl) 207 - { 208 - struct terratec *tt = video_drvdata(file); 209 - 210 - switch (ctrl->id) { 211 - case V4L2_CID_AUDIO_MUTE: 212 - if (tt->muted) 213 - ctrl->value = 1; 214 - else 215 - ctrl->value = 0; 216 - return 0; 217 - case V4L2_CID_AUDIO_VOLUME: 218 - ctrl->value = tt->curvol * 6554; 219 - return 0; 220 - } 221 - return -EINVAL; 222 - } 223 - 224 - static int vidioc_s_ctrl(struct file *file, void *priv, 225 - struct v4l2_control *ctrl) 226 - { 227 - struct terratec *tt = video_drvdata(file); 228 - 229 - switch (ctrl->id) { 230 - case V4L2_CID_AUDIO_MUTE: 231 - if (ctrl->value) 232 - tt_mute(tt); 233 - else 234 - tt_setvol(tt,tt->curvol); 235 - return 0; 236 - case V4L2_CID_AUDIO_VOLUME: 237 - tt_setvol(tt,ctrl->value); 238 - return 0; 239 - } 240 - return -EINVAL; 241 - } 242 - 243 - static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 244 - { 245 - *i = 0; 246 - return 0; 247 - } 248 - 249 - static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 250 - { 251 - return i ? -EINVAL : 0; 252 - } 253 - 254 - static int vidioc_g_audio(struct file *file, void *priv, 255 - struct v4l2_audio *a) 256 - { 257 - a->index = 0; 258 - strlcpy(a->name, "Radio", sizeof(a->name)); 259 - a->capability = V4L2_AUDCAP_STEREO; 260 - return 0; 261 - } 262 - 263 - static int vidioc_s_audio(struct file *file, void *priv, 264 - struct v4l2_audio *a) 265 - { 266 - return a->index ? -EINVAL : 0; 267 - } 268 - 269 - static const struct v4l2_file_operations terratec_fops = { 270 - .owner = THIS_MODULE, 271 - .unlocked_ioctl = video_ioctl2, 196 + static const struct radio_isa_ops terratec_ops = { 197 + .alloc = terratec_alloc, 198 + .s_mute_volume = terratec_s_mute_volume, 199 + .s_frequency = terratec_s_frequency, 200 + .g_signal = terratec_g_signal, 272 201 }; 273 202 274 - static const struct v4l2_ioctl_ops terratec_ioctl_ops = { 275 - .vidioc_querycap = vidioc_querycap, 276 - .vidioc_g_tuner = vidioc_g_tuner, 277 - .vidioc_s_tuner = vidioc_s_tuner, 278 - .vidioc_g_frequency = vidioc_g_frequency, 279 - .vidioc_s_frequency = vidioc_s_frequency, 280 - .vidioc_queryctrl = vidioc_queryctrl, 281 - .vidioc_g_ctrl = vidioc_g_ctrl, 282 - .vidioc_s_ctrl = vidioc_s_ctrl, 283 - .vidioc_g_audio = vidioc_g_audio, 284 - .vidioc_s_audio = vidioc_s_audio, 285 - .vidioc_g_input = vidioc_g_input, 286 - .vidioc_s_input = vidioc_s_input, 203 + static const int terratec_ioports[] = { 0x590 }; 204 + 205 + static struct radio_isa_driver terratec_driver = { 206 + .driver = { 207 + .match = radio_isa_match, 208 + .probe = radio_isa_probe, 209 + .remove = radio_isa_remove, 210 + .driver = { 211 + .name = "radio-terratec", 212 + }, 213 + }, 214 + .io_params = &io, 215 + .radio_nr_params = &radio_nr, 216 + .io_ports = terratec_ioports, 217 + .num_of_io_ports = ARRAY_SIZE(terratec_ioports), 218 + .region_size = 2, 219 + .card = "TerraTec ActiveRadio", 220 + .ops = &terratec_ops, 221 + .has_stereo = true, 222 + .max_volume = 10, 287 223 }; 288 224 289 225 static int __init terratec_init(void) 290 226 { 291 - struct terratec *tt = &terratec_card; 292 - struct v4l2_device *v4l2_dev = &tt->v4l2_dev; 293 - int res; 294 - 295 - strlcpy(v4l2_dev->name, "terratec", sizeof(v4l2_dev->name)); 296 - tt->io = io; 297 - if (tt->io == -1) { 298 - v4l2_err(v4l2_dev, "you must set an I/O address with io=0x590 or 0x591\n"); 299 - return -EINVAL; 300 - } 301 - if (!request_region(tt->io, 2, "terratec")) { 302 - v4l2_err(v4l2_dev, "port 0x%x already in use\n", io); 303 - return -EBUSY; 304 - } 305 - 306 - res = v4l2_device_register(NULL, v4l2_dev); 307 - if (res < 0) { 308 - release_region(tt->io, 2); 309 - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 310 - return res; 311 - } 312 - 313 - strlcpy(tt->vdev.name, v4l2_dev->name, sizeof(tt->vdev.name)); 314 - tt->vdev.v4l2_dev = v4l2_dev; 315 - tt->vdev.fops = &terratec_fops; 316 - tt->vdev.ioctl_ops = &terratec_ioctl_ops; 317 - tt->vdev.release = video_device_release_empty; 318 - video_set_drvdata(&tt->vdev, tt); 319 - 320 - mutex_init(&tt->lock); 321 - 322 - /* mute card - prevents noisy bootups */ 323 - tt_write_vol(tt, 0); 324 - 325 - if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 326 - v4l2_device_unregister(&tt->v4l2_dev); 327 - release_region(tt->io, 2); 328 - return -EINVAL; 329 - } 330 - 331 - v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); 332 - return 0; 227 + return isa_register_driver(&terratec_driver.driver, 1); 333 228 } 334 229 335 230 static void __exit terratec_exit(void) 336 231 { 337 - struct terratec *tt = &terratec_card; 338 - struct v4l2_device *v4l2_dev = &tt->v4l2_dev; 339 - 340 - video_unregister_device(&tt->vdev); 341 - v4l2_device_unregister(&tt->v4l2_dev); 342 - release_region(tt->io, 2); 343 - v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver unloaded.\n"); 232 + isa_unregister_driver(&terratec_driver.driver); 344 233 } 345 234 346 235 module_init(terratec_init);
+117 -305
drivers/media/radio/radio-trust.c
··· 21 21 #include <linux/ioport.h> 22 22 #include <linux/videodev2.h> 23 23 #include <linux/io.h> 24 + #include <linux/slab.h> 24 25 #include <media/v4l2-device.h> 25 26 #include <media/v4l2-ioctl.h> 27 + #include "radio-isa.h" 26 28 27 29 MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); 28 30 MODULE_DESCRIPTION("A driver for the Trust FM Radio card."); 29 31 MODULE_LICENSE("GPL"); 30 - MODULE_VERSION("0.0.3"); 32 + MODULE_VERSION("0.1.99"); 31 33 32 34 /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ 33 35 ··· 37 35 #define CONFIG_RADIO_TRUST_PORT -1 38 36 #endif 39 37 40 - static int io = CONFIG_RADIO_TRUST_PORT; 41 - static int radio_nr = -1; 38 + #define TRUST_MAX 2 42 39 43 - module_param(io, int, 0); 44 - MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)"); 45 - module_param(radio_nr, int, 0); 40 + static int io[TRUST_MAX] = { [0] = CONFIG_RADIO_TRUST_PORT, 41 + [1 ... (TRUST_MAX - 1)] = -1 }; 42 + static int radio_nr[TRUST_MAX] = { [0 ... (TRUST_MAX - 1)] = -1 }; 43 + 44 + module_param_array(io, int, NULL, 0444); 45 + MODULE_PARM_DESC(io, "I/O addresses of the Trust FM Radio card (0x350 or 0x358)"); 46 + module_param_array(radio_nr, int, NULL, 0444); 47 + MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 46 48 47 49 struct trust { 48 - struct v4l2_device v4l2_dev; 49 - struct video_device vdev; 50 - int io; 50 + struct radio_isa_card isa; 51 51 int ioval; 52 - __u16 curvol; 53 - __u16 curbass; 54 - __u16 curtreble; 55 - int muted; 56 - unsigned long curfreq; 57 - int curstereo; 58 - int curmute; 59 - struct mutex lock; 60 52 }; 61 53 62 - static struct trust trust_card; 54 + static struct radio_isa_card *trust_alloc(void) 55 + { 56 + struct trust *tr = kzalloc(sizeof(*tr), GFP_KERNEL); 57 + 58 + return tr ? &tr->isa : NULL; 59 + } 63 60 64 61 /* i2c addresses */ 65 62 #define TDA7318_ADDR 0x88 66 63 #define TSA6060T_ADDR 0xc4 67 64 68 - #define TR_DELAY do { inb(tr->io); inb(tr->io); inb(tr->io); } while (0) 69 - #define TR_SET_SCL outb(tr->ioval |= 2, tr->io) 70 - #define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->io) 71 - #define TR_SET_SDA outb(tr->ioval |= 1, tr->io) 72 - #define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->io) 65 + #define TR_DELAY do { inb(tr->isa.io); inb(tr->isa.io); inb(tr->isa.io); } while (0) 66 + #define TR_SET_SCL outb(tr->ioval |= 2, tr->isa.io) 67 + #define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->isa.io) 68 + #define TR_SET_SDA outb(tr->ioval |= 1, tr->isa.io) 69 + #define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->isa.io) 73 70 74 71 static void write_i2c(struct trust *tr, int n, ...) 75 72 { ··· 85 84 TR_CLR_SCL; 86 85 TR_DELAY; 87 86 88 - for(; n; n--) { 87 + for (; n; n--) { 89 88 val = va_arg(args, unsigned); 90 - for(mask = 0x80; mask; mask >>= 1) { 91 - if(val & mask) 89 + for (mask = 0x80; mask; mask >>= 1) { 90 + if (val & mask) 92 91 TR_SET_SDA; 93 92 else 94 93 TR_CLR_SDA; ··· 116 115 va_end(args); 117 116 } 118 117 119 - static void tr_setvol(struct trust *tr, __u16 vol) 118 + static int trust_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) 120 119 { 121 - mutex_lock(&tr->lock); 122 - tr->curvol = vol / 2048; 123 - write_i2c(tr, 2, TDA7318_ADDR, tr->curvol ^ 0x1f); 124 - mutex_unlock(&tr->lock); 120 + struct trust *tr = container_of(isa, struct trust, isa); 121 + 122 + tr->ioval = (tr->ioval & 0xf7) | (mute << 3); 123 + outb(tr->ioval, isa->io); 124 + write_i2c(tr, 2, TDA7318_ADDR, vol ^ 0x1f); 125 + return 0; 126 + } 127 + 128 + static int trust_s_stereo(struct radio_isa_card *isa, bool stereo) 129 + { 130 + struct trust *tr = container_of(isa, struct trust, isa); 131 + 132 + tr->ioval = (tr->ioval & 0xfb) | (!stereo << 2); 133 + outb(tr->ioval, isa->io); 134 + return 0; 135 + } 136 + 137 + static u32 trust_g_signal(struct radio_isa_card *isa) 138 + { 139 + int i, v; 140 + 141 + for (i = 0, v = 0; i < 100; i++) 142 + v |= inb(isa->io); 143 + return (v & 1) ? 0 : 0xffff; 144 + } 145 + 146 + static int trust_s_frequency(struct radio_isa_card *isa, u32 freq) 147 + { 148 + struct trust *tr = container_of(isa, struct trust, isa); 149 + 150 + freq /= 160; /* Convert to 10 kHz units */ 151 + freq += 1070; /* Add 10.7 MHz IF */ 152 + write_i2c(tr, 5, TSA6060T_ADDR, (freq << 1) | 1, 153 + freq >> 7, 0x60 | ((freq >> 15) & 1), 0); 154 + return 0; 125 155 } 126 156 127 157 static int basstreble2chip[15] = { 128 158 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8 129 159 }; 130 160 131 - static void tr_setbass(struct trust *tr, __u16 bass) 161 + static int trust_s_ctrl(struct v4l2_ctrl *ctrl) 132 162 { 133 - mutex_lock(&tr->lock); 134 - tr->curbass = bass / 4370; 135 - write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[tr->curbass]); 136 - mutex_unlock(&tr->lock); 137 - } 138 - 139 - static void tr_settreble(struct trust *tr, __u16 treble) 140 - { 141 - mutex_lock(&tr->lock); 142 - tr->curtreble = treble / 4370; 143 - write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[tr->curtreble]); 144 - mutex_unlock(&tr->lock); 145 - } 146 - 147 - static void tr_setstereo(struct trust *tr, int stereo) 148 - { 149 - mutex_lock(&tr->lock); 150 - tr->curstereo = !!stereo; 151 - tr->ioval = (tr->ioval & 0xfb) | (!tr->curstereo << 2); 152 - outb(tr->ioval, tr->io); 153 - mutex_unlock(&tr->lock); 154 - } 155 - 156 - static void tr_setmute(struct trust *tr, int mute) 157 - { 158 - mutex_lock(&tr->lock); 159 - tr->curmute = !!mute; 160 - tr->ioval = (tr->ioval & 0xf7) | (tr->curmute << 3); 161 - outb(tr->ioval, tr->io); 162 - mutex_unlock(&tr->lock); 163 - } 164 - 165 - static int tr_getsigstr(struct trust *tr) 166 - { 167 - int i, v; 168 - 169 - mutex_lock(&tr->lock); 170 - for (i = 0, v = 0; i < 100; i++) 171 - v |= inb(tr->io); 172 - mutex_unlock(&tr->lock); 173 - return (v & 1) ? 0 : 0xffff; 174 - } 175 - 176 - static int tr_getstereo(struct trust *tr) 177 - { 178 - /* don't know how to determine it, just return the setting */ 179 - return tr->curstereo; 180 - } 181 - 182 - static void tr_setfreq(struct trust *tr, unsigned long f) 183 - { 184 - mutex_lock(&tr->lock); 185 - tr->curfreq = f; 186 - f /= 160; /* Convert to 10 kHz units */ 187 - f += 1070; /* Add 10.7 MHz IF */ 188 - write_i2c(tr, 5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0); 189 - mutex_unlock(&tr->lock); 190 - } 191 - 192 - static int vidioc_querycap(struct file *file, void *priv, 193 - struct v4l2_capability *v) 194 - { 195 - strlcpy(v->driver, "radio-trust", sizeof(v->driver)); 196 - strlcpy(v->card, "Trust FM Radio", sizeof(v->card)); 197 - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 198 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 199 - return 0; 200 - } 201 - 202 - static int vidioc_g_tuner(struct file *file, void *priv, 203 - struct v4l2_tuner *v) 204 - { 205 - struct trust *tr = video_drvdata(file); 206 - 207 - if (v->index > 0) 208 - return -EINVAL; 209 - 210 - strlcpy(v->name, "FM", sizeof(v->name)); 211 - v->type = V4L2_TUNER_RADIO; 212 - v->rangelow = 87.5 * 16000; 213 - v->rangehigh = 108 * 16000; 214 - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 215 - v->capability = V4L2_TUNER_CAP_LOW; 216 - if (tr_getstereo(tr)) 217 - v->audmode = V4L2_TUNER_MODE_STEREO; 218 - else 219 - v->audmode = V4L2_TUNER_MODE_MONO; 220 - v->signal = tr_getsigstr(tr); 221 - return 0; 222 - } 223 - 224 - static int vidioc_s_tuner(struct file *file, void *priv, 225 - struct v4l2_tuner *v) 226 - { 227 - struct trust *tr = video_drvdata(file); 228 - 229 - if (v->index) 230 - return -EINVAL; 231 - tr_setstereo(tr, v->audmode == V4L2_TUNER_MODE_STEREO); 232 - return 0; 233 - } 234 - 235 - static int vidioc_s_frequency(struct file *file, void *priv, 236 - struct v4l2_frequency *f) 237 - { 238 - struct trust *tr = video_drvdata(file); 239 - 240 - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 241 - return -EINVAL; 242 - tr_setfreq(tr, f->frequency); 243 - return 0; 244 - } 245 - 246 - static int vidioc_g_frequency(struct file *file, void *priv, 247 - struct v4l2_frequency *f) 248 - { 249 - struct trust *tr = video_drvdata(file); 250 - 251 - if (f->tuner != 0) 252 - return -EINVAL; 253 - f->type = V4L2_TUNER_RADIO; 254 - f->frequency = tr->curfreq; 255 - return 0; 256 - } 257 - 258 - static int vidioc_queryctrl(struct file *file, void *priv, 259 - struct v4l2_queryctrl *qc) 260 - { 261 - switch (qc->id) { 262 - case V4L2_CID_AUDIO_MUTE: 263 - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 264 - case V4L2_CID_AUDIO_VOLUME: 265 - return v4l2_ctrl_query_fill(qc, 0, 65535, 2048, 65535); 266 - case V4L2_CID_AUDIO_BASS: 267 - case V4L2_CID_AUDIO_TREBLE: 268 - return v4l2_ctrl_query_fill(qc, 0, 65535, 4370, 32768); 269 - } 270 - return -EINVAL; 271 - } 272 - 273 - static int vidioc_g_ctrl(struct file *file, void *priv, 274 - struct v4l2_control *ctrl) 275 - { 276 - struct trust *tr = video_drvdata(file); 163 + struct radio_isa_card *isa = 164 + container_of(ctrl->handler, struct radio_isa_card, hdl); 165 + struct trust *tr = container_of(isa, struct trust, isa); 277 166 278 167 switch (ctrl->id) { 279 - case V4L2_CID_AUDIO_MUTE: 280 - ctrl->value = tr->curmute; 281 - return 0; 282 - case V4L2_CID_AUDIO_VOLUME: 283 - ctrl->value = tr->curvol * 2048; 284 - return 0; 285 168 case V4L2_CID_AUDIO_BASS: 286 - ctrl->value = tr->curbass * 4370; 169 + write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[ctrl->val]); 287 170 return 0; 288 171 case V4L2_CID_AUDIO_TREBLE: 289 - ctrl->value = tr->curtreble * 4370; 172 + write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[ctrl->val]); 290 173 return 0; 291 174 } 292 175 return -EINVAL; 293 176 } 294 177 295 - static int vidioc_s_ctrl(struct file *file, void *priv, 296 - struct v4l2_control *ctrl) 297 - { 298 - struct trust *tr = video_drvdata(file); 299 - 300 - switch (ctrl->id) { 301 - case V4L2_CID_AUDIO_MUTE: 302 - tr_setmute(tr, ctrl->value); 303 - return 0; 304 - case V4L2_CID_AUDIO_VOLUME: 305 - tr_setvol(tr, ctrl->value); 306 - return 0; 307 - case V4L2_CID_AUDIO_BASS: 308 - tr_setbass(tr, ctrl->value); 309 - return 0; 310 - case V4L2_CID_AUDIO_TREBLE: 311 - tr_settreble(tr, ctrl->value); 312 - return 0; 313 - } 314 - return -EINVAL; 315 - } 316 - 317 - static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 318 - { 319 - *i = 0; 320 - return 0; 321 - } 322 - 323 - static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 324 - { 325 - return i ? -EINVAL : 0; 326 - } 327 - 328 - static int vidioc_g_audio(struct file *file, void *priv, 329 - struct v4l2_audio *a) 330 - { 331 - a->index = 0; 332 - strlcpy(a->name, "Radio", sizeof(a->name)); 333 - a->capability = V4L2_AUDCAP_STEREO; 334 - return 0; 335 - } 336 - 337 - static int vidioc_s_audio(struct file *file, void *priv, 338 - struct v4l2_audio *a) 339 - { 340 - return a->index ? -EINVAL : 0; 341 - } 342 - 343 - static const struct v4l2_file_operations trust_fops = { 344 - .owner = THIS_MODULE, 345 - .unlocked_ioctl = video_ioctl2, 178 + static const struct v4l2_ctrl_ops trust_ctrl_ops = { 179 + .s_ctrl = trust_s_ctrl, 346 180 }; 347 181 348 - static const struct v4l2_ioctl_ops trust_ioctl_ops = { 349 - .vidioc_querycap = vidioc_querycap, 350 - .vidioc_g_tuner = vidioc_g_tuner, 351 - .vidioc_s_tuner = vidioc_s_tuner, 352 - .vidioc_g_frequency = vidioc_g_frequency, 353 - .vidioc_s_frequency = vidioc_s_frequency, 354 - .vidioc_queryctrl = vidioc_queryctrl, 355 - .vidioc_g_ctrl = vidioc_g_ctrl, 356 - .vidioc_s_ctrl = vidioc_s_ctrl, 357 - .vidioc_g_audio = vidioc_g_audio, 358 - .vidioc_s_audio = vidioc_s_audio, 359 - .vidioc_g_input = vidioc_g_input, 360 - .vidioc_s_input = vidioc_s_input, 361 - }; 362 - 363 - static int __init trust_init(void) 182 + static int trust_initialize(struct radio_isa_card *isa) 364 183 { 365 - struct trust *tr = &trust_card; 366 - struct v4l2_device *v4l2_dev = &tr->v4l2_dev; 367 - int res; 184 + struct trust *tr = container_of(isa, struct trust, isa); 368 185 369 - strlcpy(v4l2_dev->name, "trust", sizeof(v4l2_dev->name)); 370 - tr->io = io; 371 186 tr->ioval = 0xf; 372 - mutex_init(&tr->lock); 373 - 374 - if (tr->io == -1) { 375 - v4l2_err(v4l2_dev, "You must set an I/O address with io=0x0x350 or 0x358\n"); 376 - return -EINVAL; 377 - } 378 - if (!request_region(tr->io, 2, "Trust FM Radio")) { 379 - v4l2_err(v4l2_dev, "port 0x%x already in use\n", tr->io); 380 - return -EBUSY; 381 - } 382 - 383 - res = v4l2_device_register(NULL, v4l2_dev); 384 - if (res < 0) { 385 - release_region(tr->io, 2); 386 - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 387 - return res; 388 - } 389 - 390 - strlcpy(tr->vdev.name, v4l2_dev->name, sizeof(tr->vdev.name)); 391 - tr->vdev.v4l2_dev = v4l2_dev; 392 - tr->vdev.fops = &trust_fops; 393 - tr->vdev.ioctl_ops = &trust_ioctl_ops; 394 - tr->vdev.release = video_device_release_empty; 395 - video_set_drvdata(&tr->vdev, tr); 396 - 397 187 write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ 398 188 write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ 399 189 write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ 400 190 write_i2c(tr, 2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */ 401 191 write_i2c(tr, 2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */ 402 192 403 - tr_setvol(tr, 0xffff); 404 - tr_setbass(tr, 0x8000); 405 - tr_settreble(tr, 0x8000); 406 - tr_setstereo(tr, 1); 407 - 408 - /* mute card - prevents noisy bootups */ 409 - tr_setmute(tr, 1); 410 - 411 - if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 412 - v4l2_device_unregister(v4l2_dev); 413 - release_region(tr->io, 2); 414 - return -EINVAL; 415 - } 416 - 417 - v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); 418 - 419 - return 0; 193 + v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops, 194 + V4L2_CID_AUDIO_BASS, 0, 15, 1, 8); 195 + v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops, 196 + V4L2_CID_AUDIO_TREBLE, 0, 15, 1, 8); 197 + return isa->hdl.error; 420 198 } 421 199 422 - static void __exit cleanup_trust_module(void) 423 - { 424 - struct trust *tr = &trust_card; 200 + static const struct radio_isa_ops trust_ops = { 201 + .init = trust_initialize, 202 + .alloc = trust_alloc, 203 + .s_mute_volume = trust_s_mute_volume, 204 + .s_frequency = trust_s_frequency, 205 + .s_stereo = trust_s_stereo, 206 + .g_signal = trust_g_signal, 207 + }; 425 208 426 - video_unregister_device(&tr->vdev); 427 - v4l2_device_unregister(&tr->v4l2_dev); 428 - release_region(tr->io, 2); 209 + static const int trust_ioports[] = { 0x350, 0x358 }; 210 + 211 + static struct radio_isa_driver trust_driver = { 212 + .driver = { 213 + .match = radio_isa_match, 214 + .probe = radio_isa_probe, 215 + .remove = radio_isa_remove, 216 + .driver = { 217 + .name = "radio-trust", 218 + }, 219 + }, 220 + .io_params = io, 221 + .radio_nr_params = radio_nr, 222 + .io_ports = trust_ioports, 223 + .num_of_io_ports = ARRAY_SIZE(trust_ioports), 224 + .region_size = 2, 225 + .card = "Trust FM Radio", 226 + .ops = &trust_ops, 227 + .has_stereo = true, 228 + .max_volume = 31, 229 + }; 230 + 231 + static int __init trust_init(void) 232 + { 233 + return isa_register_driver(&trust_driver.driver, TRUST_MAX); 234 + } 235 + 236 + static void __exit trust_exit(void) 237 + { 238 + isa_unregister_driver(&trust_driver.driver); 429 239 } 430 240 431 241 module_init(trust_init); 432 - module_exit(cleanup_trust_module); 242 + module_exit(trust_exit);
+70 -296
drivers/media/radio/radio-typhoon.c
··· 33 33 #include <linux/ioport.h> /* request_region */ 34 34 #include <linux/videodev2.h> /* kernel radio structs */ 35 35 #include <linux/io.h> /* outb, outb_p */ 36 + #include <linux/slab.h> 36 37 #include <media/v4l2-device.h> 37 38 #include <media/v4l2-ioctl.h> 39 + #include "radio-isa.h" 38 40 39 41 #define DRIVER_VERSION "0.1.2" 40 42 41 43 MODULE_AUTHOR("Dr. Henrik Seidel"); 42 44 MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio)."); 43 45 MODULE_LICENSE("GPL"); 44 - MODULE_VERSION(DRIVER_VERSION); 46 + MODULE_VERSION("0.1.99"); 45 47 46 48 #ifndef CONFIG_RADIO_TYPHOON_PORT 47 49 #define CONFIG_RADIO_TYPHOON_PORT -1 48 50 #endif 49 51 50 52 #ifndef CONFIG_RADIO_TYPHOON_MUTEFREQ 51 - #define CONFIG_RADIO_TYPHOON_MUTEFREQ 0 53 + #define CONFIG_RADIO_TYPHOON_MUTEFREQ 87000 52 54 #endif 53 55 54 - static int io = CONFIG_RADIO_TYPHOON_PORT; 55 - static int radio_nr = -1; 56 + #define TYPHOON_MAX 2 56 57 57 - module_param(io, int, 0); 58 - MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)"); 59 - 60 - module_param(radio_nr, int, 0); 61 - 58 + static int io[TYPHOON_MAX] = { [0] = CONFIG_RADIO_TYPHOON_PORT, 59 + [1 ... (TYPHOON_MAX - 1)] = -1 }; 60 + static int radio_nr[TYPHOON_MAX] = { [0 ... (TYPHOON_MAX - 1)] = -1 }; 62 61 static unsigned long mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ; 62 + 63 + module_param_array(io, int, NULL, 0444); 64 + MODULE_PARM_DESC(io, "I/O addresses of the Typhoon card (0x316 or 0x336)"); 65 + module_param_array(radio_nr, int, NULL, 0444); 66 + MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 63 67 module_param(mutefreq, ulong, 0); 64 68 MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)"); 65 69 66 - #define BANNER "Typhoon Radio Card driver v" DRIVER_VERSION "\n" 67 - 68 70 struct typhoon { 69 - struct v4l2_device v4l2_dev; 70 - struct video_device vdev; 71 - int io; 72 - int curvol; 71 + struct radio_isa_card isa; 73 72 int muted; 74 - unsigned long curfreq; 75 - unsigned long mutefreq; 76 - struct mutex lock; 77 73 }; 78 74 79 - static struct typhoon typhoon_card; 80 - 81 - static void typhoon_setvol_generic(struct typhoon *dev, int vol) 75 + static struct radio_isa_card *typhoon_alloc(void) 82 76 { 83 - mutex_lock(&dev->lock); 84 - vol >>= 14; /* Map 16 bit to 2 bit */ 85 - vol &= 3; 86 - outb_p(vol / 2, dev->io); /* Set the volume, high bit. */ 87 - outb_p(vol % 2, dev->io + 2); /* Set the volume, low bit. */ 88 - mutex_unlock(&dev->lock); 77 + struct typhoon *ty = kzalloc(sizeof(*ty), GFP_KERNEL); 78 + 79 + return ty ? &ty->isa : NULL; 89 80 } 90 81 91 - static int typhoon_setfreq_generic(struct typhoon *dev, 92 - unsigned long frequency) 82 + static int typhoon_s_frequency(struct radio_isa_card *isa, u32 freq) 93 83 { 94 84 unsigned long outval; 95 85 unsigned long x; ··· 95 105 * 96 106 */ 97 107 98 - mutex_lock(&dev->lock); 99 - x = frequency / 160; 108 + x = freq / 160; 100 109 outval = (x * x + 2500) / 5000; 101 110 outval = (outval * x + 5000) / 10000; 102 111 outval -= (10 * x * x + 10433) / 20866; 103 112 outval += 4 * x - 11505; 104 113 105 - outb_p((outval >> 8) & 0x01, dev->io + 4); 106 - outb_p(outval >> 9, dev->io + 6); 107 - outb_p(outval & 0xff, dev->io + 8); 108 - mutex_unlock(&dev->lock); 109 - 114 + outb_p((outval >> 8) & 0x01, isa->io + 4); 115 + outb_p(outval >> 9, isa->io + 6); 116 + outb_p(outval & 0xff, isa->io + 8); 110 117 return 0; 111 118 } 112 119 113 - static int typhoon_setfreq(struct typhoon *dev, unsigned long frequency) 120 + static int typhoon_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) 114 121 { 115 - typhoon_setfreq_generic(dev, frequency); 116 - dev->curfreq = frequency; 117 - return 0; 118 - } 122 + struct typhoon *ty = container_of(isa, struct typhoon, isa); 119 123 120 - static void typhoon_mute(struct typhoon *dev) 121 - { 122 - if (dev->muted == 1) 123 - return; 124 - typhoon_setvol_generic(dev, 0); 125 - typhoon_setfreq_generic(dev, dev->mutefreq); 126 - dev->muted = 1; 127 - } 124 + if (mute) 125 + vol = 0; 126 + vol >>= 14; /* Map 16 bit to 2 bit */ 127 + vol &= 3; 128 + outb_p(vol / 2, isa->io); /* Set the volume, high bit. */ 129 + outb_p(vol % 2, isa->io + 2); /* Set the volume, low bit. */ 128 130 129 - static void typhoon_unmute(struct typhoon *dev) 130 - { 131 - if (dev->muted == 0) 132 - return; 133 - typhoon_setfreq_generic(dev, dev->curfreq); 134 - typhoon_setvol_generic(dev, dev->curvol); 135 - dev->muted = 0; 136 - } 137 - 138 - static int typhoon_setvol(struct typhoon *dev, int vol) 139 - { 140 - if (dev->muted && vol != 0) { /* user is unmuting the card */ 141 - dev->curvol = vol; 142 - typhoon_unmute(dev); 143 - return 0; 131 + if (vol == 0 && !ty->muted) { 132 + ty->muted = true; 133 + return typhoon_s_frequency(isa, mutefreq << 4); 144 134 } 145 - if (vol == dev->curvol) /* requested volume == current */ 146 - return 0; 147 - 148 - if (vol == 0) { /* volume == 0 means mute the card */ 149 - typhoon_mute(dev); 150 - dev->curvol = vol; 151 - return 0; 135 + if (vol && ty->muted) { 136 + ty->muted = false; 137 + return typhoon_s_frequency(isa, isa->freq); 152 138 } 153 - typhoon_setvol_generic(dev, vol); 154 - dev->curvol = vol; 155 139 return 0; 156 140 } 157 141 158 - static int vidioc_querycap(struct file *file, void *priv, 159 - struct v4l2_capability *v) 160 - { 161 - strlcpy(v->driver, "radio-typhoon", sizeof(v->driver)); 162 - strlcpy(v->card, "Typhoon Radio", sizeof(v->card)); 163 - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 164 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 165 - return 0; 166 - } 167 - 168 - static int vidioc_g_tuner(struct file *file, void *priv, 169 - struct v4l2_tuner *v) 170 - { 171 - if (v->index > 0) 172 - return -EINVAL; 173 - 174 - strlcpy(v->name, "FM", sizeof(v->name)); 175 - v->type = V4L2_TUNER_RADIO; 176 - v->rangelow = 87.5 * 16000; 177 - v->rangehigh = 108 * 16000; 178 - v->rxsubchans = V4L2_TUNER_SUB_MONO; 179 - v->capability = V4L2_TUNER_CAP_LOW; 180 - v->audmode = V4L2_TUNER_MODE_MONO; 181 - v->signal = 0xFFFF; /* We can't get the signal strength */ 182 - return 0; 183 - } 184 - 185 - static int vidioc_s_tuner(struct file *file, void *priv, 186 - struct v4l2_tuner *v) 187 - { 188 - return v->index ? -EINVAL : 0; 189 - } 190 - 191 - static int vidioc_g_frequency(struct file *file, void *priv, 192 - struct v4l2_frequency *f) 193 - { 194 - struct typhoon *dev = video_drvdata(file); 195 - 196 - if (f->tuner != 0) 197 - return -EINVAL; 198 - f->type = V4L2_TUNER_RADIO; 199 - f->frequency = dev->curfreq; 200 - return 0; 201 - } 202 - 203 - static int vidioc_s_frequency(struct file *file, void *priv, 204 - struct v4l2_frequency *f) 205 - { 206 - struct typhoon *dev = video_drvdata(file); 207 - 208 - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 209 - return -EINVAL; 210 - dev->curfreq = f->frequency; 211 - typhoon_setfreq(dev, dev->curfreq); 212 - return 0; 213 - } 214 - 215 - static int vidioc_queryctrl(struct file *file, void *priv, 216 - struct v4l2_queryctrl *qc) 217 - { 218 - switch (qc->id) { 219 - case V4L2_CID_AUDIO_MUTE: 220 - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 221 - case V4L2_CID_AUDIO_VOLUME: 222 - return v4l2_ctrl_query_fill(qc, 0, 65535, 16384, 65535); 223 - } 224 - return -EINVAL; 225 - } 226 - 227 - static int vidioc_g_ctrl(struct file *file, void *priv, 228 - struct v4l2_control *ctrl) 229 - { 230 - struct typhoon *dev = video_drvdata(file); 231 - 232 - switch (ctrl->id) { 233 - case V4L2_CID_AUDIO_MUTE: 234 - ctrl->value = dev->muted; 235 - return 0; 236 - case V4L2_CID_AUDIO_VOLUME: 237 - ctrl->value = dev->curvol; 238 - return 0; 239 - } 240 - return -EINVAL; 241 - } 242 - 243 - static int vidioc_s_ctrl (struct file *file, void *priv, 244 - struct v4l2_control *ctrl) 245 - { 246 - struct typhoon *dev = video_drvdata(file); 247 - 248 - switch (ctrl->id) { 249 - case V4L2_CID_AUDIO_MUTE: 250 - if (ctrl->value) 251 - typhoon_mute(dev); 252 - else 253 - typhoon_unmute(dev); 254 - return 0; 255 - case V4L2_CID_AUDIO_VOLUME: 256 - typhoon_setvol(dev, ctrl->value); 257 - return 0; 258 - } 259 - return -EINVAL; 260 - } 261 - 262 - static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 263 - { 264 - *i = 0; 265 - return 0; 266 - } 267 - 268 - static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 269 - { 270 - return i ? -EINVAL : 0; 271 - } 272 - 273 - static int vidioc_g_audio(struct file *file, void *priv, 274 - struct v4l2_audio *a) 275 - { 276 - a->index = 0; 277 - strlcpy(a->name, "Radio", sizeof(a->name)); 278 - a->capability = V4L2_AUDCAP_STEREO; 279 - return 0; 280 - } 281 - 282 - static int vidioc_s_audio(struct file *file, void *priv, 283 - struct v4l2_audio *a) 284 - { 285 - return a->index ? -EINVAL : 0; 286 - } 287 - 288 - static int vidioc_log_status(struct file *file, void *priv) 289 - { 290 - struct typhoon *dev = video_drvdata(file); 291 - struct v4l2_device *v4l2_dev = &dev->v4l2_dev; 292 - 293 - v4l2_info(v4l2_dev, BANNER); 294 - #ifdef MODULE 295 - v4l2_info(v4l2_dev, "Load type: Driver loaded as a module\n\n"); 296 - #else 297 - v4l2_info(v4l2_dev, "Load type: Driver compiled into kernel\n\n"); 298 - #endif 299 - v4l2_info(v4l2_dev, "frequency = %lu kHz\n", dev->curfreq >> 4); 300 - v4l2_info(v4l2_dev, "volume = %d\n", dev->curvol); 301 - v4l2_info(v4l2_dev, "mute = %s\n", dev->muted ? "on" : "off"); 302 - v4l2_info(v4l2_dev, "io = 0x%x\n", dev->io); 303 - v4l2_info(v4l2_dev, "mute frequency = %lu kHz\n", dev->mutefreq >> 4); 304 - return 0; 305 - } 306 - 307 - static const struct v4l2_file_operations typhoon_fops = { 308 - .owner = THIS_MODULE, 309 - .unlocked_ioctl = video_ioctl2, 142 + static const struct radio_isa_ops typhoon_ops = { 143 + .alloc = typhoon_alloc, 144 + .s_mute_volume = typhoon_s_mute_volume, 145 + .s_frequency = typhoon_s_frequency, 310 146 }; 311 147 312 - static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { 313 - .vidioc_log_status = vidioc_log_status, 314 - .vidioc_querycap = vidioc_querycap, 315 - .vidioc_g_tuner = vidioc_g_tuner, 316 - .vidioc_s_tuner = vidioc_s_tuner, 317 - .vidioc_g_audio = vidioc_g_audio, 318 - .vidioc_s_audio = vidioc_s_audio, 319 - .vidioc_g_input = vidioc_g_input, 320 - .vidioc_s_input = vidioc_s_input, 321 - .vidioc_g_frequency = vidioc_g_frequency, 322 - .vidioc_s_frequency = vidioc_s_frequency, 323 - .vidioc_queryctrl = vidioc_queryctrl, 324 - .vidioc_g_ctrl = vidioc_g_ctrl, 325 - .vidioc_s_ctrl = vidioc_s_ctrl, 148 + static const int typhoon_ioports[] = { 0x316, 0x336 }; 149 + 150 + static struct radio_isa_driver typhoon_driver = { 151 + .driver = { 152 + .match = radio_isa_match, 153 + .probe = radio_isa_probe, 154 + .remove = radio_isa_remove, 155 + .driver = { 156 + .name = "radio-typhoon", 157 + }, 158 + }, 159 + .io_params = io, 160 + .radio_nr_params = radio_nr, 161 + .io_ports = typhoon_ioports, 162 + .num_of_io_ports = ARRAY_SIZE(typhoon_ioports), 163 + .region_size = 8, 164 + .card = "Typhoon Radio", 165 + .ops = &typhoon_ops, 166 + .has_stereo = true, 167 + .max_volume = 3, 326 168 }; 327 169 328 170 static int __init typhoon_init(void) 329 171 { 330 - struct typhoon *dev = &typhoon_card; 331 - struct v4l2_device *v4l2_dev = &dev->v4l2_dev; 332 - int res; 333 - 334 - strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); 335 - dev->io = io; 336 - 337 - if (dev->io == -1) { 338 - v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); 339 - return -EINVAL; 172 + if (mutefreq < 87000 || mutefreq > 108000) { 173 + printk(KERN_ERR "%s: You must set a frequency (in kHz) used when muting the card,\n", 174 + typhoon_driver.driver.driver.name); 175 + printk(KERN_ERR "%s: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108000)\n", 176 + typhoon_driver.driver.driver.name); 177 + return -ENODEV; 340 178 } 341 - 342 - if (mutefreq < 87000 || mutefreq > 108500) { 343 - v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); 344 - v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); 345 - return -EINVAL; 346 - } 347 - dev->curfreq = dev->mutefreq = mutefreq << 4; 348 - 349 - mutex_init(&dev->lock); 350 - if (!request_region(dev->io, 8, "typhoon")) { 351 - v4l2_err(v4l2_dev, "port 0x%x already in use\n", 352 - dev->io); 353 - return -EBUSY; 354 - } 355 - 356 - res = v4l2_device_register(NULL, v4l2_dev); 357 - if (res < 0) { 358 - release_region(dev->io, 8); 359 - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 360 - return res; 361 - } 362 - v4l2_info(v4l2_dev, BANNER); 363 - 364 - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); 365 - dev->vdev.v4l2_dev = v4l2_dev; 366 - dev->vdev.fops = &typhoon_fops; 367 - dev->vdev.ioctl_ops = &typhoon_ioctl_ops; 368 - dev->vdev.release = video_device_release_empty; 369 - video_set_drvdata(&dev->vdev, dev); 370 - 371 - /* mute card - prevents noisy bootups */ 372 - typhoon_mute(dev); 373 - 374 - if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 375 - v4l2_device_unregister(&dev->v4l2_dev); 376 - release_region(dev->io, 8); 377 - return -EINVAL; 378 - } 379 - v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); 380 - v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq); 381 - 382 - return 0; 179 + return isa_register_driver(&typhoon_driver.driver, TYPHOON_MAX); 383 180 } 384 181 385 182 static void __exit typhoon_exit(void) 386 183 { 387 - struct typhoon *dev = &typhoon_card; 388 - 389 - video_unregister_device(&dev->vdev); 390 - v4l2_device_unregister(&dev->v4l2_dev); 391 - release_region(dev->io, 8); 184 + isa_unregister_driver(&typhoon_driver.driver); 392 185 } 186 + 393 187 394 188 module_init(typhoon_init); 395 189 module_exit(typhoon_exit);
+118 -336
drivers/media/radio/radio-zoltrix.c
··· 1 - /* zoltrix radio plus driver for Linux radio support 2 - * (c) 1998 C. van Schaik <carl@leg.uct.ac.za> 1 + /* 2 + * Zoltrix Radio Plus driver 3 + * Copyright 1998 C. van Schaik <carl@leg.uct.ac.za> 3 4 * 4 5 * BUGS 5 6 * Due to the inconsistency in reading from the signal flags ··· 28 27 * 29 28 * 2006-07-24 - Converted to V4L2 API 30 29 * by Mauro Carvalho Chehab <mchehab@infradead.org> 30 + * 31 + * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com> 32 + * 33 + * Note that this is the driver for the Zoltrix Radio Plus. 34 + * This driver does not work for the Zoltrix Radio Plus 108 or the 35 + * Zoltrix Radio Plus for Windows. 36 + * 37 + * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool. 31 38 */ 32 39 33 40 #include <linux/module.h> /* Modules */ ··· 45 36 #include <linux/videodev2.h> /* kernel radio structs */ 46 37 #include <linux/mutex.h> 47 38 #include <linux/io.h> /* outb, outb_p */ 39 + #include <linux/slab.h> 48 40 #include <media/v4l2-device.h> 49 41 #include <media/v4l2-ioctl.h> 42 + #include "radio-isa.h" 50 43 51 - MODULE_AUTHOR("C.van Schaik"); 44 + MODULE_AUTHOR("C. van Schaik"); 52 45 MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus."); 53 46 MODULE_LICENSE("GPL"); 54 - MODULE_VERSION("0.0.3"); 47 + MODULE_VERSION("0.1.99"); 55 48 56 49 #ifndef CONFIG_RADIO_ZOLTRIX_PORT 57 50 #define CONFIG_RADIO_ZOLTRIX_PORT -1 58 51 #endif 59 52 60 - static int io = CONFIG_RADIO_ZOLTRIX_PORT; 61 - static int radio_nr = -1; 53 + #define ZOLTRIX_MAX 2 62 54 63 - module_param(io, int, 0); 64 - MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)"); 65 - module_param(radio_nr, int, 0); 55 + static int io[ZOLTRIX_MAX] = { [0] = CONFIG_RADIO_ZOLTRIX_PORT, 56 + [1 ... (ZOLTRIX_MAX - 1)] = -1 }; 57 + static int radio_nr[ZOLTRIX_MAX] = { [0 ... (ZOLTRIX_MAX - 1)] = -1 }; 58 + 59 + module_param_array(io, int, NULL, 0444); 60 + MODULE_PARM_DESC(io, "I/O addresses of the Zoltrix Radio Plus card (0x20c or 0x30c)"); 61 + module_param_array(radio_nr, int, NULL, 0444); 62 + MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 66 63 67 64 struct zoltrix { 68 - struct v4l2_device v4l2_dev; 69 - struct video_device vdev; 70 - int io; 65 + struct radio_isa_card isa; 71 66 int curvol; 72 - unsigned long curfreq; 73 - int muted; 74 - unsigned int stereo; 75 - struct mutex lock; 67 + bool muted; 76 68 }; 77 69 78 - static struct zoltrix zoltrix_card; 79 - 80 - static int zol_setvol(struct zoltrix *zol, int vol) 70 + static struct radio_isa_card *zoltrix_alloc(void) 81 71 { 82 - zol->curvol = vol; 83 - if (zol->muted) 84 - return 0; 72 + struct zoltrix *zol = kzalloc(sizeof(*zol), GFP_KERNEL); 85 73 86 - mutex_lock(&zol->lock); 87 - if (vol == 0) { 88 - outb(0, zol->io); 89 - outb(0, zol->io); 90 - inb(zol->io + 3); /* Zoltrix needs to be read to confirm */ 91 - mutex_unlock(&zol->lock); 74 + return zol ? &zol->isa : NULL; 75 + } 76 + 77 + static int zoltrix_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) 78 + { 79 + struct zoltrix *zol = container_of(isa, struct zoltrix, isa); 80 + 81 + zol->curvol = vol; 82 + zol->muted = mute; 83 + if (mute || vol == 0) { 84 + outb(0, isa->io); 85 + outb(0, isa->io); 86 + inb(isa->io + 3); /* Zoltrix needs to be read to confirm */ 92 87 return 0; 93 88 } 94 89 95 - outb(zol->curvol-1, zol->io); 90 + outb(vol - 1, isa->io); 96 91 msleep(10); 97 - inb(zol->io + 2); 98 - mutex_unlock(&zol->lock); 92 + inb(isa->io + 2); 99 93 return 0; 100 94 } 101 95 102 - static void zol_mute(struct zoltrix *zol) 96 + /* tunes the radio to the desired frequency */ 97 + static int zoltrix_s_frequency(struct radio_isa_card *isa, u32 freq) 103 98 { 104 - zol->muted = 1; 105 - mutex_lock(&zol->lock); 106 - outb(0, zol->io); 107 - outb(0, zol->io); 108 - inb(zol->io + 3); /* Zoltrix needs to be read to confirm */ 109 - mutex_unlock(&zol->lock); 110 - } 111 - 112 - static void zol_unmute(struct zoltrix *zol) 113 - { 114 - zol->muted = 0; 115 - zol_setvol(zol, zol->curvol); 116 - } 117 - 118 - static int zol_setfreq(struct zoltrix *zol, unsigned long freq) 119 - { 120 - /* tunes the radio to the desired frequency */ 121 - struct v4l2_device *v4l2_dev = &zol->v4l2_dev; 99 + struct zoltrix *zol = container_of(isa, struct zoltrix, isa); 100 + struct v4l2_device *v4l2_dev = &isa->v4l2_dev; 122 101 unsigned long long bitmask, f, m; 123 - unsigned int stereo = zol->stereo; 102 + bool stereo = isa->stereo; 124 103 int i; 125 104 126 105 if (freq == 0) { ··· 122 125 bitmask = 0xc480402c10080000ull; 123 126 i = 45; 124 127 125 - mutex_lock(&zol->lock); 128 + outb(0, isa->io); 129 + outb(0, isa->io); 130 + inb(isa->io + 3); /* Zoltrix needs to be read to confirm */ 126 131 127 - zol->curfreq = freq; 128 - 129 - outb(0, zol->io); 130 - outb(0, zol->io); 131 - inb(zol->io + 3); /* Zoltrix needs to be read to confirm */ 132 - 133 - outb(0x40, zol->io); 134 - outb(0xc0, zol->io); 132 + outb(0x40, isa->io); 133 + outb(0xc0, isa->io); 135 134 136 135 bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ (stereo << 31)); 137 136 while (i--) { 138 137 if ((bitmask & 0x8000000000000000ull) != 0) { 139 - outb(0x80, zol->io); 138 + outb(0x80, isa->io); 140 139 udelay(50); 141 - outb(0x00, zol->io); 140 + outb(0x00, isa->io); 142 141 udelay(50); 143 - outb(0x80, zol->io); 142 + outb(0x80, isa->io); 144 143 udelay(50); 145 144 } else { 146 - outb(0xc0, zol->io); 145 + outb(0xc0, isa->io); 147 146 udelay(50); 148 - outb(0x40, zol->io); 147 + outb(0x40, isa->io); 149 148 udelay(50); 150 - outb(0xc0, zol->io); 149 + outb(0xc0, isa->io); 151 150 udelay(50); 152 151 } 153 152 bitmask *= 2; 154 153 } 155 154 /* termination sequence */ 156 - outb(0x80, zol->io); 157 - outb(0xc0, zol->io); 158 - outb(0x40, zol->io); 155 + outb(0x80, isa->io); 156 + outb(0xc0, isa->io); 157 + outb(0x40, isa->io); 159 158 udelay(1000); 160 - inb(zol->io + 2); 161 - 159 + inb(isa->io + 2); 162 160 udelay(1000); 163 161 164 - if (zol->muted) { 165 - outb(0, zol->io); 166 - outb(0, zol->io); 167 - inb(zol->io + 3); 168 - udelay(1000); 169 - } 170 - 171 - mutex_unlock(&zol->lock); 172 - 173 - if (!zol->muted) 174 - zol_setvol(zol, zol->curvol); 175 - return 0; 162 + return zoltrix_s_mute_volume(isa, zol->muted, zol->curvol); 176 163 } 177 164 178 165 /* Get signal strength */ 179 - static int zol_getsigstr(struct zoltrix *zol) 166 + static u32 zoltrix_g_rxsubchans(struct radio_isa_card *isa) 180 167 { 168 + struct zoltrix *zol = container_of(isa, struct zoltrix, isa); 181 169 int a, b; 182 170 183 - mutex_lock(&zol->lock); 184 - outb(0x00, zol->io); /* This stuff I found to do nothing */ 185 - outb(zol->curvol, zol->io); 171 + outb(0x00, isa->io); /* This stuff I found to do nothing */ 172 + outb(zol->curvol, isa->io); 186 173 msleep(20); 187 174 188 - a = inb(zol->io); 175 + a = inb(isa->io); 189 176 msleep(10); 190 - b = inb(zol->io); 177 + b = inb(isa->io); 191 178 192 - mutex_unlock(&zol->lock); 179 + return (a == b && a == 0xcf) ? 180 + V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; 181 + } 182 + 183 + static u32 zoltrix_g_signal(struct radio_isa_card *isa) 184 + { 185 + struct zoltrix *zol = container_of(isa, struct zoltrix, isa); 186 + int a, b; 187 + 188 + outb(0x00, isa->io); /* This stuff I found to do nothing */ 189 + outb(zol->curvol, isa->io); 190 + msleep(20); 191 + 192 + a = inb(isa->io); 193 + msleep(10); 194 + b = inb(isa->io); 193 195 194 196 if (a != b) 195 197 return 0; 196 198 197 199 /* I found this out by playing with a binary scanner on the card io */ 198 - return a == 0xcf || a == 0xdf || a == 0xef; 200 + return (a == 0xcf || a == 0xdf || a == 0xef) ? 0xffff : 0; 199 201 } 200 202 201 - static int zol_is_stereo(struct zoltrix *zol) 203 + static int zoltrix_s_stereo(struct radio_isa_card *isa, bool stereo) 202 204 { 203 - int x1, x2; 204 - 205 - mutex_lock(&zol->lock); 206 - 207 - outb(0x00, zol->io); 208 - outb(zol->curvol, zol->io); 209 - msleep(20); 210 - 211 - x1 = inb(zol->io); 212 - msleep(10); 213 - x2 = inb(zol->io); 214 - 215 - mutex_unlock(&zol->lock); 216 - 217 - return x1 == x2 && x1 == 0xcf; 205 + return zoltrix_s_frequency(isa, isa->freq); 218 206 } 219 207 220 - static int vidioc_querycap(struct file *file, void *priv, 221 - struct v4l2_capability *v) 222 - { 223 - strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver)); 224 - strlcpy(v->card, "Zoltrix Radio", sizeof(v->card)); 225 - strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 226 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 227 - return 0; 228 - } 229 - 230 - static int vidioc_g_tuner(struct file *file, void *priv, 231 - struct v4l2_tuner *v) 232 - { 233 - struct zoltrix *zol = video_drvdata(file); 234 - 235 - if (v->index > 0) 236 - return -EINVAL; 237 - 238 - strlcpy(v->name, "FM", sizeof(v->name)); 239 - v->type = V4L2_TUNER_RADIO; 240 - v->rangelow = 88 * 16000; 241 - v->rangehigh = 108 * 16000; 242 - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 243 - v->capability = V4L2_TUNER_CAP_LOW; 244 - if (zol_is_stereo(zol)) 245 - v->audmode = V4L2_TUNER_MODE_STEREO; 246 - else 247 - v->audmode = V4L2_TUNER_MODE_MONO; 248 - v->signal = 0xFFFF * zol_getsigstr(zol); 249 - return 0; 250 - } 251 - 252 - static int vidioc_s_tuner(struct file *file, void *priv, 253 - struct v4l2_tuner *v) 254 - { 255 - return v->index ? -EINVAL : 0; 256 - } 257 - 258 - static int vidioc_s_frequency(struct file *file, void *priv, 259 - struct v4l2_frequency *f) 260 - { 261 - struct zoltrix *zol = video_drvdata(file); 262 - 263 - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 264 - return -EINVAL; 265 - if (zol_setfreq(zol, f->frequency) != 0) 266 - return -EINVAL; 267 - return 0; 268 - } 269 - 270 - static int vidioc_g_frequency(struct file *file, void *priv, 271 - struct v4l2_frequency *f) 272 - { 273 - struct zoltrix *zol = video_drvdata(file); 274 - 275 - if (f->tuner != 0) 276 - return -EINVAL; 277 - f->type = V4L2_TUNER_RADIO; 278 - f->frequency = zol->curfreq; 279 - return 0; 280 - } 281 - 282 - static int vidioc_queryctrl(struct file *file, void *priv, 283 - struct v4l2_queryctrl *qc) 284 - { 285 - switch (qc->id) { 286 - case V4L2_CID_AUDIO_MUTE: 287 - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 288 - case V4L2_CID_AUDIO_VOLUME: 289 - return v4l2_ctrl_query_fill(qc, 0, 65535, 4096, 65535); 290 - } 291 - return -EINVAL; 292 - } 293 - 294 - static int vidioc_g_ctrl(struct file *file, void *priv, 295 - struct v4l2_control *ctrl) 296 - { 297 - struct zoltrix *zol = video_drvdata(file); 298 - 299 - switch (ctrl->id) { 300 - case V4L2_CID_AUDIO_MUTE: 301 - ctrl->value = zol->muted; 302 - return 0; 303 - case V4L2_CID_AUDIO_VOLUME: 304 - ctrl->value = zol->curvol * 4096; 305 - return 0; 306 - } 307 - return -EINVAL; 308 - } 309 - 310 - static int vidioc_s_ctrl(struct file *file, void *priv, 311 - struct v4l2_control *ctrl) 312 - { 313 - struct zoltrix *zol = video_drvdata(file); 314 - 315 - switch (ctrl->id) { 316 - case V4L2_CID_AUDIO_MUTE: 317 - if (ctrl->value) 318 - zol_mute(zol); 319 - else { 320 - zol_unmute(zol); 321 - zol_setvol(zol, zol->curvol); 322 - } 323 - return 0; 324 - case V4L2_CID_AUDIO_VOLUME: 325 - zol_setvol(zol, ctrl->value / 4096); 326 - return 0; 327 - } 328 - zol->stereo = 1; 329 - if (zol_setfreq(zol, zol->curfreq) != 0) 330 - return -EINVAL; 331 - #if 0 332 - /* FIXME: Implement stereo/mono switch on V4L2 */ 333 - if (v->mode & VIDEO_SOUND_STEREO) { 334 - zol->stereo = 1; 335 - zol_setfreq(zol, zol->curfreq); 336 - } 337 - if (v->mode & VIDEO_SOUND_MONO) { 338 - zol->stereo = 0; 339 - zol_setfreq(zol, zol->curfreq); 340 - } 341 - #endif 342 - return -EINVAL; 343 - } 344 - 345 - static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 346 - { 347 - *i = 0; 348 - return 0; 349 - } 350 - 351 - static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 352 - { 353 - return i ? -EINVAL : 0; 354 - } 355 - 356 - static int vidioc_g_audio(struct file *file, void *priv, 357 - struct v4l2_audio *a) 358 - { 359 - a->index = 0; 360 - strlcpy(a->name, "Radio", sizeof(a->name)); 361 - a->capability = V4L2_AUDCAP_STEREO; 362 - return 0; 363 - } 364 - 365 - static int vidioc_s_audio(struct file *file, void *priv, 366 - struct v4l2_audio *a) 367 - { 368 - return a->index ? -EINVAL : 0; 369 - } 370 - 371 - static const struct v4l2_file_operations zoltrix_fops = 372 - { 373 - .owner = THIS_MODULE, 374 - .unlocked_ioctl = video_ioctl2, 208 + static const struct radio_isa_ops zoltrix_ops = { 209 + .alloc = zoltrix_alloc, 210 + .s_mute_volume = zoltrix_s_mute_volume, 211 + .s_frequency = zoltrix_s_frequency, 212 + .s_stereo = zoltrix_s_stereo, 213 + .g_rxsubchans = zoltrix_g_rxsubchans, 214 + .g_signal = zoltrix_g_signal, 375 215 }; 376 216 377 - static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { 378 - .vidioc_querycap = vidioc_querycap, 379 - .vidioc_g_tuner = vidioc_g_tuner, 380 - .vidioc_s_tuner = vidioc_s_tuner, 381 - .vidioc_g_audio = vidioc_g_audio, 382 - .vidioc_s_audio = vidioc_s_audio, 383 - .vidioc_g_input = vidioc_g_input, 384 - .vidioc_s_input = vidioc_s_input, 385 - .vidioc_g_frequency = vidioc_g_frequency, 386 - .vidioc_s_frequency = vidioc_s_frequency, 387 - .vidioc_queryctrl = vidioc_queryctrl, 388 - .vidioc_g_ctrl = vidioc_g_ctrl, 389 - .vidioc_s_ctrl = vidioc_s_ctrl, 217 + static const int zoltrix_ioports[] = { 0x20c, 0x30c }; 218 + 219 + static struct radio_isa_driver zoltrix_driver = { 220 + .driver = { 221 + .match = radio_isa_match, 222 + .probe = radio_isa_probe, 223 + .remove = radio_isa_remove, 224 + .driver = { 225 + .name = "radio-zoltrix", 226 + }, 227 + }, 228 + .io_params = io, 229 + .radio_nr_params = radio_nr, 230 + .io_ports = zoltrix_ioports, 231 + .num_of_io_ports = ARRAY_SIZE(zoltrix_ioports), 232 + .region_size = 2, 233 + .card = "Zoltrix Radio Plus", 234 + .ops = &zoltrix_ops, 235 + .has_stereo = true, 236 + .max_volume = 15, 390 237 }; 391 238 392 239 static int __init zoltrix_init(void) 393 240 { 394 - struct zoltrix *zol = &zoltrix_card; 395 - struct v4l2_device *v4l2_dev = &zol->v4l2_dev; 396 - int res; 397 - 398 - strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name)); 399 - zol->io = io; 400 - if (zol->io == -1) { 401 - v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or 0x30c\n"); 402 - return -EINVAL; 403 - } 404 - if (zol->io != 0x20c && zol->io != 0x30c) { 405 - v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n"); 406 - return -ENXIO; 407 - } 408 - 409 - if (!request_region(zol->io, 2, "zoltrix")) { 410 - v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io); 411 - return -EBUSY; 412 - } 413 - 414 - res = v4l2_device_register(NULL, v4l2_dev); 415 - if (res < 0) { 416 - release_region(zol->io, 2); 417 - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 418 - return res; 419 - } 420 - 421 - mutex_init(&zol->lock); 422 - 423 - /* mute card - prevents noisy bootups */ 424 - 425 - /* this ensures that the volume is all the way down */ 426 - 427 - outb(0, zol->io); 428 - outb(0, zol->io); 429 - msleep(20); 430 - inb(zol->io + 3); 431 - 432 - zol->curvol = 0; 433 - zol->stereo = 1; 434 - 435 - strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); 436 - zol->vdev.v4l2_dev = v4l2_dev; 437 - zol->vdev.fops = &zoltrix_fops; 438 - zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; 439 - zol->vdev.release = video_device_release_empty; 440 - video_set_drvdata(&zol->vdev, zol); 441 - 442 - if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 443 - v4l2_device_unregister(v4l2_dev); 444 - release_region(zol->io, 2); 445 - return -EINVAL; 446 - } 447 - v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); 448 - 449 - return 0; 241 + return isa_register_driver(&zoltrix_driver.driver, ZOLTRIX_MAX); 450 242 } 451 243 452 244 static void __exit zoltrix_exit(void) 453 245 { 454 - struct zoltrix *zol = &zoltrix_card; 455 - 456 - video_unregister_device(&zol->vdev); 457 - v4l2_device_unregister(&zol->v4l2_dev); 458 - release_region(zol->io, 2); 246 + isa_unregister_driver(&zoltrix_driver.driver); 459 247 } 460 248 461 249 module_init(zoltrix_init);
+1 -12
drivers/media/radio/saa7706h.c
··· 434 434 .id_table = saa7706h_id, 435 435 }; 436 436 437 - static __init int saa7706h_init(void) 438 - { 439 - return i2c_add_driver(&saa7706h_driver); 440 - } 441 - 442 - static __exit void saa7706h_exit(void) 443 - { 444 - i2c_del_driver(&saa7706h_driver); 445 - } 446 - 447 - module_init(saa7706h_init); 448 - module_exit(saa7706h_exit); 437 + module_i2c_driver(saa7706h_driver); 449 438 450 439 MODULE_DESCRIPTION("SAA7706H Car Radio DSP driver"); 451 440 MODULE_AUTHOR("Mocean Laboratories");
+1 -27
drivers/media/radio/si470x/radio-si470x-i2c.c
··· 539 539 .id_table = si470x_i2c_id, 540 540 }; 541 541 542 - 543 - 544 - /************************************************************************** 545 - * Module Interface 546 - **************************************************************************/ 547 - 548 - /* 549 - * si470x_i2c_init - module init 550 - */ 551 - static int __init si470x_i2c_init(void) 552 - { 553 - printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n"); 554 - return i2c_add_driver(&si470x_i2c_driver); 555 - } 556 - 557 - 558 - /* 559 - * si470x_i2c_exit - module exit 560 - */ 561 - static void __exit si470x_i2c_exit(void) 562 - { 563 - i2c_del_driver(&si470x_i2c_driver); 564 - } 565 - 566 - 567 - module_init(si470x_i2c_init); 568 - module_exit(si470x_i2c_exit); 542 + module_i2c_driver(si470x_i2c_driver); 569 543 570 544 MODULE_LICENSE("GPL"); 571 545 MODULE_AUTHOR(DRIVER_AUTHOR);
+1 -14
drivers/media/radio/si4713-i2c.c
··· 2106 2106 .id_table = si4713_id, 2107 2107 }; 2108 2108 2109 - /* Module Interface */ 2110 - static int __init si4713_module_init(void) 2111 - { 2112 - return i2c_add_driver(&si4713_i2c_driver); 2113 - } 2114 - 2115 - static void __exit si4713_module_exit(void) 2116 - { 2117 - i2c_del_driver(&si4713_i2c_driver); 2118 - } 2119 - 2120 - module_init(si4713_module_init); 2121 - module_exit(si4713_module_exit); 2122 - 2109 + module_i2c_driver(si4713_i2c_driver);
+1 -13
drivers/media/radio/tef6862.c
··· 215 215 .id_table = tef6862_id, 216 216 }; 217 217 218 - static __init int tef6862_init(void) 219 - { 220 - return i2c_add_driver(&tef6862_driver); 221 - } 222 - 223 - static __exit void tef6862_exit(void) 224 - { 225 - i2c_del_driver(&tef6862_driver); 226 - } 227 - 228 - module_init(tef6862_init); 229 - module_exit(tef6862_exit); 218 + module_i2c_driver(tef6862_driver); 230 219 231 220 MODULE_DESCRIPTION("TEF6862 Car Radio Enhanced Selectivity Tuner"); 232 221 MODULE_AUTHOR("Mocean Laboratories"); 233 222 MODULE_LICENSE("GPL v2"); 234 -
+9
drivers/media/rc/Kconfig
··· 266 266 To compile this driver as a module, choose M here: the module will 267 267 be called rc_loopback. 268 268 269 + config IR_GPIO_CIR 270 + tristate "GPIO IR remote control" 271 + depends on RC_CORE 272 + ---help--- 273 + Say Y if you want to use GPIO based IR Receiver. 274 + 275 + To compile this driver as a module, choose M here: the module will 276 + be called gpio-ir-recv. 277 + 269 278 endif #RC_CORE
+1
drivers/media/rc/Makefile
··· 26 26 obj-$(CONFIG_IR_STREAMZAP) += streamzap.o 27 27 obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o 28 28 obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o 29 + obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o
+18 -8
drivers/media/rc/fintek-cir.c
··· 117 117 static void cir_dump_regs(struct fintek_dev *fintek) 118 118 { 119 119 fintek_config_mode_enable(fintek); 120 - fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 120 + fintek_select_logical_dev(fintek, fintek->logical_dev_cir); 121 121 122 122 pr_reg("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME); 123 123 pr_reg(" * CR CIR BASE ADDR: 0x%x\n", ··· 143 143 u8 chip_major, chip_minor; 144 144 u8 vendor_major, vendor_minor; 145 145 u8 portsel, ir_class; 146 - u16 vendor; 146 + u16 vendor, chip; 147 147 int ret = 0; 148 148 149 149 fintek_config_mode_enable(fintek); ··· 176 176 177 177 chip_major = fintek_cr_read(fintek, GCR_CHIP_ID_HI); 178 178 chip_minor = fintek_cr_read(fintek, GCR_CHIP_ID_LO); 179 + chip = chip_major << 8 | chip_minor; 179 180 180 181 vendor_major = fintek_cr_read(fintek, GCR_VENDOR_ID_HI); 181 182 vendor_minor = fintek_cr_read(fintek, GCR_VENDOR_ID_LO); ··· 193 192 fintek->chip_major = chip_major; 194 193 fintek->chip_minor = chip_minor; 195 194 fintek->chip_vendor = vendor; 195 + 196 + /* 197 + * Newer reviews of this chipset uses port 8 instead of 5 198 + */ 199 + if ((chip != 0x0408) || (chip != 0x0804)) 200 + fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV2; 201 + else 202 + fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV1; 203 + 196 204 spin_unlock_irqrestore(&fintek->fintek_lock, flags); 197 205 198 206 return ret; ··· 210 200 static void fintek_cir_ldev_init(struct fintek_dev *fintek) 211 201 { 212 202 /* Select CIR logical device and enable */ 213 - fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 203 + fintek_select_logical_dev(fintek, fintek->logical_dev_cir); 214 204 fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN); 215 205 216 206 /* Write allocated CIR address and IRQ information to hardware */ ··· 391 381 fit_dbg_verbose("%s firing", __func__); 392 382 393 383 fintek_config_mode_enable(fintek); 394 - fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 384 + fintek_select_logical_dev(fintek, fintek->logical_dev_cir); 395 385 fintek_config_mode_disable(fintek); 396 386 397 387 /* ··· 432 422 fintek_config_mode_enable(fintek); 433 423 434 424 /* enable the CIR logical device */ 435 - fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 425 + fintek_select_logical_dev(fintek, fintek->logical_dev_cir); 436 426 fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN); 437 427 438 428 fintek_config_mode_disable(fintek); ··· 449 439 fintek_config_mode_enable(fintek); 450 440 451 441 /* disable the CIR logical device */ 452 - fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 442 + fintek_select_logical_dev(fintek, fintek->logical_dev_cir); 453 443 fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN); 454 444 455 445 fintek_config_mode_disable(fintek); ··· 621 611 fintek_config_mode_enable(fintek); 622 612 623 613 /* disable cir logical dev */ 624 - fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 614 + fintek_select_logical_dev(fintek, fintek->logical_dev_cir); 625 615 fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN); 626 616 627 617 fintek_config_mode_disable(fintek); ··· 644 634 645 635 /* Enable CIR logical device */ 646 636 fintek_config_mode_enable(fintek); 647 - fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 637 + fintek_select_logical_dev(fintek, fintek->logical_dev_cir); 648 638 fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN); 649 639 650 640 fintek_config_mode_disable(fintek);
+3 -1
drivers/media/rc/fintek-cir.h
··· 88 88 u8 chip_major; 89 89 u8 chip_minor; 90 90 u16 chip_vendor; 91 + u8 logical_dev_cir; 91 92 92 93 /* hardware features */ 93 94 bool hw_learning_capable; ··· 173 172 #define LOGICAL_DEV_ENABLE 0x01 174 173 175 174 /* Logical device number of the CIR function */ 176 - #define LOGICAL_DEV_CIR 0x05 175 + #define LOGICAL_DEV_CIR_REV1 0x05 176 + #define LOGICAL_DEV_CIR_REV2 0x08 177 177 178 178 /* CIR Logical Device (LDN 0x08) config registers */ 179 179 #define CIR_CR_COMMAND_INDEX 0x04
+205
drivers/media/rc/gpio-ir-recv.c
··· 1 + /* Copyright (c) 2012, Code Aurora Forum. All rights reserved. 2 + * 3 + * This program is free software; you can redistribute it and/or modify 4 + * it under the terms of the GNU General Public License version 2 and 5 + * only version 2 as published by the Free Software Foundation. 6 + * 7 + * This program is distributed in the hope that it will be useful, 8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 + * GNU General Public License for more details. 11 + */ 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/init.h> 15 + #include <linux/module.h> 16 + #include <linux/interrupt.h> 17 + #include <linux/gpio.h> 18 + #include <linux/slab.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/irq.h> 21 + #include <media/rc-core.h> 22 + #include <media/gpio-ir-recv.h> 23 + 24 + #define GPIO_IR_DRIVER_NAME "gpio-rc-recv" 25 + #define GPIO_IR_DEVICE_NAME "gpio_ir_recv" 26 + 27 + struct gpio_rc_dev { 28 + struct rc_dev *rcdev; 29 + int gpio_nr; 30 + bool active_low; 31 + }; 32 + 33 + static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) 34 + { 35 + struct gpio_rc_dev *gpio_dev = dev_id; 36 + int gval; 37 + int rc = 0; 38 + enum raw_event_type type = IR_SPACE; 39 + 40 + gval = gpio_get_value_cansleep(gpio_dev->gpio_nr); 41 + 42 + if (gval < 0) 43 + goto err_get_value; 44 + 45 + if (gpio_dev->active_low) 46 + gval = !gval; 47 + 48 + if (gval == 1) 49 + type = IR_PULSE; 50 + 51 + rc = ir_raw_event_store_edge(gpio_dev->rcdev, type); 52 + if (rc < 0) 53 + goto err_get_value; 54 + 55 + ir_raw_event_handle(gpio_dev->rcdev); 56 + 57 + err_get_value: 58 + return IRQ_HANDLED; 59 + } 60 + 61 + static int __devinit gpio_ir_recv_probe(struct platform_device *pdev) 62 + { 63 + struct gpio_rc_dev *gpio_dev; 64 + struct rc_dev *rcdev; 65 + const struct gpio_ir_recv_platform_data *pdata = 66 + pdev->dev.platform_data; 67 + int rc; 68 + 69 + if (!pdata) 70 + return -EINVAL; 71 + 72 + if (pdata->gpio_nr < 0) 73 + return -EINVAL; 74 + 75 + gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL); 76 + if (!gpio_dev) 77 + return -ENOMEM; 78 + 79 + rcdev = rc_allocate_device(); 80 + if (!rcdev) { 81 + rc = -ENOMEM; 82 + goto err_allocate_device; 83 + } 84 + 85 + rcdev->driver_type = RC_DRIVER_IR_RAW; 86 + rcdev->allowed_protos = RC_TYPE_ALL; 87 + rcdev->input_name = GPIO_IR_DEVICE_NAME; 88 + rcdev->input_id.bustype = BUS_HOST; 89 + rcdev->driver_name = GPIO_IR_DRIVER_NAME; 90 + rcdev->map_name = RC_MAP_EMPTY; 91 + 92 + gpio_dev->rcdev = rcdev; 93 + gpio_dev->gpio_nr = pdata->gpio_nr; 94 + gpio_dev->active_low = pdata->active_low; 95 + 96 + rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv"); 97 + if (rc < 0) 98 + goto err_gpio_request; 99 + rc = gpio_direction_input(pdata->gpio_nr); 100 + if (rc < 0) 101 + goto err_gpio_direction_input; 102 + 103 + rc = rc_register_device(rcdev); 104 + if (rc < 0) { 105 + dev_err(&pdev->dev, "failed to register rc device\n"); 106 + goto err_register_rc_device; 107 + } 108 + 109 + platform_set_drvdata(pdev, gpio_dev); 110 + 111 + rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr), 112 + gpio_ir_recv_irq, 113 + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 114 + "gpio-ir-recv-irq", gpio_dev); 115 + if (rc < 0) 116 + goto err_request_irq; 117 + 118 + return 0; 119 + 120 + err_request_irq: 121 + platform_set_drvdata(pdev, NULL); 122 + rc_unregister_device(rcdev); 123 + err_register_rc_device: 124 + err_gpio_direction_input: 125 + gpio_free(pdata->gpio_nr); 126 + err_gpio_request: 127 + rc_free_device(rcdev); 128 + rcdev = NULL; 129 + err_allocate_device: 130 + kfree(gpio_dev); 131 + return rc; 132 + } 133 + 134 + static int __devexit gpio_ir_recv_remove(struct platform_device *pdev) 135 + { 136 + struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); 137 + 138 + free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev); 139 + platform_set_drvdata(pdev, NULL); 140 + rc_unregister_device(gpio_dev->rcdev); 141 + gpio_free(gpio_dev->gpio_nr); 142 + rc_free_device(gpio_dev->rcdev); 143 + kfree(gpio_dev); 144 + return 0; 145 + } 146 + 147 + #ifdef CONFIG_PM 148 + static int gpio_ir_recv_suspend(struct device *dev) 149 + { 150 + struct platform_device *pdev = to_platform_device(dev); 151 + struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); 152 + 153 + if (device_may_wakeup(dev)) 154 + enable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr)); 155 + else 156 + disable_irq(gpio_to_irq(gpio_dev->gpio_nr)); 157 + 158 + return 0; 159 + } 160 + 161 + static int gpio_ir_recv_resume(struct device *dev) 162 + { 163 + struct platform_device *pdev = to_platform_device(dev); 164 + struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); 165 + 166 + if (device_may_wakeup(dev)) 167 + disable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr)); 168 + else 169 + enable_irq(gpio_to_irq(gpio_dev->gpio_nr)); 170 + 171 + return 0; 172 + } 173 + 174 + static const struct dev_pm_ops gpio_ir_recv_pm_ops = { 175 + .suspend = gpio_ir_recv_suspend, 176 + .resume = gpio_ir_recv_resume, 177 + }; 178 + #endif 179 + 180 + static struct platform_driver gpio_ir_recv_driver = { 181 + .probe = gpio_ir_recv_probe, 182 + .remove = __devexit_p(gpio_ir_recv_remove), 183 + .driver = { 184 + .name = GPIO_IR_DRIVER_NAME, 185 + .owner = THIS_MODULE, 186 + #ifdef CONFIG_PM 187 + .pm = &gpio_ir_recv_pm_ops, 188 + #endif 189 + }, 190 + }; 191 + 192 + static int __init gpio_ir_recv_init(void) 193 + { 194 + return platform_driver_register(&gpio_ir_recv_driver); 195 + } 196 + module_init(gpio_ir_recv_init); 197 + 198 + static void __exit gpio_ir_recv_exit(void) 199 + { 200 + platform_driver_unregister(&gpio_ir_recv_driver); 201 + } 202 + module_exit(gpio_ir_recv_exit); 203 + 204 + MODULE_DESCRIPTION("GPIO IR Receiver driver"); 205 + MODULE_LICENSE("GPL v2");
+1 -1
drivers/media/rc/ir-sony-decoder.c
··· 130 130 case 15: 131 131 device = bitrev8((data->bits >> 0) & 0xFF); 132 132 subdevice = 0; 133 - function = bitrev8((data->bits >> 7) & 0xFD); 133 + function = bitrev8((data->bits >> 7) & 0xFE); 134 134 break; 135 135 case 20: 136 136 device = bitrev8((data->bits >> 5) & 0xF8);
+3
drivers/media/rc/keymaps/Makefile
··· 41 41 rc-imon-mce.o \ 42 42 rc-imon-pad.o \ 43 43 rc-iodata-bctv7e.o \ 44 + rc-it913x-v1.o \ 45 + rc-it913x-v2.o \ 44 46 rc-kaiomy.o \ 45 47 rc-kworld-315u.o \ 48 + rc-kworld-pc150u.o \ 46 49 rc-kworld-plus-tv-analog.o \ 47 50 rc-leadtek-y04g0051.o \ 48 51 rc-lirc.o \
+95
drivers/media/rc/keymaps/rc-it913x-v1.c
··· 1 + /* ITE Generic remotes Version 1 2 + * 3 + * Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.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; either version 2 of the License, or 8 + * (at your option) any later version. 9 + */ 10 + 11 + #include <media/rc-map.h> 12 + #include <linux/module.h> 13 + 14 + 15 + static struct rc_map_table it913x_v1_rc[] = { 16 + /* Type 1 */ 17 + { 0x61d601, KEY_VIDEO }, /* Source */ 18 + { 0x61d602, KEY_3 }, 19 + { 0x61d603, KEY_POWER }, /* ShutDown */ 20 + { 0x61d604, KEY_1 }, 21 + { 0x61d605, KEY_5 }, 22 + { 0x61d606, KEY_6 }, 23 + { 0x61d607, KEY_CHANNELDOWN }, /* CH- */ 24 + { 0x61d608, KEY_2 }, 25 + { 0x61d609, KEY_CHANNELUP }, /* CH+ */ 26 + { 0x61d60a, KEY_9 }, 27 + { 0x61d60b, KEY_ZOOM }, /* Zoom */ 28 + { 0x61d60c, KEY_7 }, 29 + { 0x61d60d, KEY_8 }, 30 + { 0x61d60e, KEY_VOLUMEUP }, /* Vol+ */ 31 + { 0x61d60f, KEY_4 }, 32 + { 0x61d610, KEY_ESC }, /* [back up arrow] */ 33 + { 0x61d611, KEY_0 }, 34 + { 0x61d612, KEY_OK }, /* [enter arrow] */ 35 + { 0x61d613, KEY_VOLUMEDOWN }, /* Vol- */ 36 + { 0x61d614, KEY_RECORD }, /* Rec */ 37 + { 0x61d615, KEY_STOP }, /* Stop */ 38 + { 0x61d616, KEY_PLAY }, /* Play */ 39 + { 0x61d617, KEY_MUTE }, /* Mute */ 40 + { 0x61d618, KEY_UP }, 41 + { 0x61d619, KEY_DOWN }, 42 + { 0x61d61a, KEY_LEFT }, 43 + { 0x61d61b, KEY_RIGHT }, 44 + { 0x61d61c, KEY_RED }, 45 + { 0x61d61d, KEY_GREEN }, 46 + { 0x61d61e, KEY_YELLOW }, 47 + { 0x61d61f, KEY_BLUE }, 48 + { 0x61d643, KEY_POWER2 }, /* [red power button] */ 49 + /* Type 2 - 20 buttons */ 50 + { 0x807f0d, KEY_0 }, 51 + { 0x807f04, KEY_1 }, 52 + { 0x807f05, KEY_2 }, 53 + { 0x807f06, KEY_3 }, 54 + { 0x807f07, KEY_4 }, 55 + { 0x807f08, KEY_5 }, 56 + { 0x807f09, KEY_6 }, 57 + { 0x807f0a, KEY_7 }, 58 + { 0x807f1b, KEY_8 }, 59 + { 0x807f1f, KEY_9 }, 60 + { 0x807f12, KEY_POWER }, 61 + { 0x807f01, KEY_MEDIA_REPEAT}, /* Recall */ 62 + { 0x807f19, KEY_PAUSE }, /* Timeshift */ 63 + { 0x807f1e, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */ 64 + { 0x807f03, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/ 65 + { 0x807f1a, KEY_CHANNELUP }, 66 + { 0x807f02, KEY_CHANNELDOWN }, 67 + { 0x807f0c, KEY_ZOOM }, 68 + { 0x807f00, KEY_RECORD }, 69 + { 0x807f0e, KEY_STOP }, 70 + }; 71 + 72 + static struct rc_map_list it913x_v1_map = { 73 + .map = { 74 + .scan = it913x_v1_rc, 75 + .size = ARRAY_SIZE(it913x_v1_rc), 76 + .rc_type = RC_TYPE_NEC, 77 + .name = RC_MAP_IT913X_V1, 78 + } 79 + }; 80 + 81 + static int __init init_rc_it913x_v1_map(void) 82 + { 83 + return rc_map_register(&it913x_v1_map); 84 + } 85 + 86 + static void __exit exit_rc_it913x_v1_map(void) 87 + { 88 + rc_map_unregister(&it913x_v1_map); 89 + } 90 + 91 + module_init(init_rc_it913x_v1_map) 92 + module_exit(exit_rc_it913x_v1_map) 93 + 94 + MODULE_LICENSE("GPL"); 95 + MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
+94
drivers/media/rc/keymaps/rc-it913x-v2.c
··· 1 + /* ITE Generic remotes Version 2 2 + * 3 + * Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.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; either version 2 of the License, or 8 + * (at your option) any later version. 9 + */ 10 + 11 + #include <media/rc-map.h> 12 + #include <linux/module.h> 13 + 14 + 15 + static struct rc_map_table it913x_v2_rc[] = { 16 + /* Type 1 */ 17 + /* 9005 remote */ 18 + { 0x807f12, KEY_POWER2 }, /* Power (RED POWER BUTTON)*/ 19 + { 0x807f1a, KEY_VIDEO }, /* Source */ 20 + { 0x807f1e, KEY_MUTE }, /* Mute */ 21 + { 0x807f01, KEY_RECORD }, /* Record */ 22 + { 0x807f02, KEY_CHANNELUP }, /* Channel+ */ 23 + { 0x807f03, KEY_TIME }, /* TimeShift */ 24 + { 0x807f04, KEY_VOLUMEUP }, /* Volume- */ 25 + { 0x807f05, KEY_SCREEN }, /* FullScreen */ 26 + { 0x807f06, KEY_VOLUMEDOWN }, /* Volume- */ 27 + { 0x807f07, KEY_0 }, /* 0 */ 28 + { 0x807f08, KEY_CHANNELDOWN }, /* Channel- */ 29 + { 0x807f09, KEY_PREVIOUS }, /* Recall */ 30 + { 0x807f0a, KEY_1 }, /* 1 */ 31 + { 0x807f1b, KEY_2 }, /* 2 */ 32 + { 0x807f1f, KEY_3 }, /* 3 */ 33 + { 0x807f0c, KEY_4 }, /* 4 */ 34 + { 0x807f0d, KEY_5 }, /* 5 */ 35 + { 0x807f0e, KEY_6 }, /* 6 */ 36 + { 0x807f00, KEY_7 }, /* 7 */ 37 + { 0x807f0f, KEY_8 }, /* 8 */ 38 + { 0x807f19, KEY_9 }, /* 9 */ 39 + 40 + /* Type 2 */ 41 + /* keys stereo, snapshot unassigned */ 42 + { 0x866b00, KEY_0 }, 43 + { 0x866b1b, KEY_1 }, 44 + { 0x866b02, KEY_2 }, 45 + { 0x866b03, KEY_3 }, 46 + { 0x866b04, KEY_4 }, 47 + { 0x866b05, KEY_5 }, 48 + { 0x866b06, KEY_6 }, 49 + { 0x866b07, KEY_7 }, 50 + { 0x866b08, KEY_8 }, 51 + { 0x866b09, KEY_9 }, 52 + { 0x866b12, KEY_POWER }, 53 + { 0x866b13, KEY_MUTE }, 54 + { 0x866b0a, KEY_PREVIOUS }, /* Recall */ 55 + { 0x866b1e, KEY_PAUSE }, 56 + { 0x866b0c, KEY_VOLUMEUP }, 57 + { 0x866b18, KEY_VOLUMEDOWN }, 58 + { 0x866b0b, KEY_CHANNELUP }, 59 + { 0x866b18, KEY_CHANNELDOWN }, 60 + { 0x866b10, KEY_ZOOM }, 61 + { 0x866b1d, KEY_RECORD }, 62 + { 0x866b0e, KEY_STOP }, 63 + { 0x866b11, KEY_EPG}, 64 + { 0x866b1a, KEY_FASTFORWARD }, 65 + { 0x866b0f, KEY_REWIND }, 66 + { 0x866b1c, KEY_TV }, 67 + { 0x866b1b, KEY_TEXT }, 68 + 69 + }; 70 + 71 + static struct rc_map_list it913x_v2_map = { 72 + .map = { 73 + .scan = it913x_v2_rc, 74 + .size = ARRAY_SIZE(it913x_v2_rc), 75 + .rc_type = RC_TYPE_NEC, 76 + .name = RC_MAP_IT913X_V2, 77 + } 78 + }; 79 + 80 + static int __init init_rc_it913x_v2_map(void) 81 + { 82 + return rc_map_register(&it913x_v2_map); 83 + } 84 + 85 + static void __exit exit_rc_it913x_v2_map(void) 86 + { 87 + rc_map_unregister(&it913x_v2_map); 88 + } 89 + 90 + module_init(init_rc_it913x_v2_map) 91 + module_exit(exit_rc_it913x_v2_map) 92 + 93 + MODULE_LICENSE("GPL"); 94 + MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
+102
drivers/media/rc/keymaps/rc-kworld-pc150u.c
··· 1 + /* kworld-pc150u.c - Keytable for kworld_pc150u Remote Controller 2 + * 3 + * keymap imported from ir-keymaps.c 4 + * 5 + * Copyright (c) 2010 by Kyle Strickland 6 + * (based on kworld-plus-tv-analog.c by 7 + * Mauro Carvalho Chehab <mchehab@redhat.com>) 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License as published by 11 + * the Free Software Foundation; either version 2 of the License, or 12 + * (at your option) any later version. 13 + */ 14 + 15 + #include <media/rc-map.h> 16 + #include <linux/module.h> 17 + 18 + /* Kworld PC150-U 19 + Kyle Strickland <kyle@kyle.strickland.name> 20 + */ 21 + 22 + static struct rc_map_table kworld_pc150u[] = { 23 + { 0x0c, KEY_MEDIA }, /* Kworld key */ 24 + { 0x16, KEY_EJECTCLOSECD }, /* -> ) */ 25 + { 0x1d, KEY_POWER2 }, 26 + 27 + { 0x00, KEY_1 }, 28 + { 0x01, KEY_2 }, 29 + { 0x02, KEY_3 }, 30 + { 0x03, KEY_4 }, 31 + { 0x04, KEY_5 }, 32 + { 0x05, KEY_6 }, 33 + { 0x06, KEY_7 }, 34 + { 0x07, KEY_8 }, 35 + { 0x08, KEY_9 }, 36 + { 0x0a, KEY_0 }, 37 + 38 + { 0x09, KEY_AGAIN }, 39 + { 0x14, KEY_MUTE }, 40 + 41 + { 0x1e, KEY_LAST }, 42 + { 0x17, KEY_ZOOM }, 43 + { 0x1f, KEY_HOMEPAGE }, 44 + { 0x0e, KEY_ESC }, 45 + 46 + { 0x20, KEY_UP }, 47 + { 0x21, KEY_DOWN }, 48 + { 0x42, KEY_LEFT }, 49 + { 0x43, KEY_RIGHT }, 50 + { 0x0b, KEY_ENTER }, 51 + 52 + { 0x10, KEY_CHANNELUP }, 53 + { 0x11, KEY_CHANNELDOWN }, 54 + 55 + { 0x13, KEY_VOLUMEUP }, 56 + { 0x12, KEY_VOLUMEDOWN }, 57 + 58 + { 0x19, KEY_TIME}, /* Timeshift */ 59 + { 0x1a, KEY_STOP}, 60 + { 0x1b, KEY_RECORD}, 61 + { 0x4b, KEY_EMAIL}, 62 + 63 + { 0x40, KEY_REWIND}, 64 + { 0x44, KEY_PLAYPAUSE}, 65 + { 0x41, KEY_FORWARD}, 66 + { 0x22, KEY_TEXT}, 67 + 68 + { 0x15, KEY_AUDIO}, /* ((*)) */ 69 + { 0x0f, KEY_MODE}, /* display ratio */ 70 + { 0x1c, KEY_SYSRQ}, /* snapshot */ 71 + { 0x4a, KEY_SLEEP}, /* sleep timer */ 72 + 73 + { 0x48, KEY_SOUND}, /* switch theater mode */ 74 + { 0x49, KEY_BLUE}, /* A */ 75 + { 0x18, KEY_RED}, /* B */ 76 + { 0x23, KEY_GREEN}, /* C */ 77 + }; 78 + 79 + static struct rc_map_list kworld_pc150u_map = { 80 + .map = { 81 + .scan = kworld_pc150u, 82 + .size = ARRAY_SIZE(kworld_pc150u), 83 + .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ 84 + .name = RC_MAP_KWORLD_PC150U, 85 + } 86 + }; 87 + 88 + static int __init init_rc_map_kworld_pc150u(void) 89 + { 90 + return rc_map_register(&kworld_pc150u_map); 91 + } 92 + 93 + static void __exit exit_rc_map_kworld_pc150u(void) 94 + { 95 + rc_map_unregister(&kworld_pc150u_map); 96 + } 97 + 98 + module_init(init_rc_map_kworld_pc150u) 99 + module_exit(exit_rc_map_kworld_pc150u) 100 + 101 + MODULE_LICENSE("GPL"); 102 + MODULE_AUTHOR("Kyle Strickland <kyle@kyle.strickland.name>");
+52
drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
··· 18 18 */ 19 19 20 20 static struct rc_map_table nec_terratec_cinergy_xs[] = { 21 + 22 + /* Terratec Grey IR, with most keys in orange */ 21 23 { 0x1441, KEY_HOME}, 22 24 { 0x1401, KEY_POWER2}, 23 25 ··· 80 78 { 0x144e, KEY_REWIND}, 81 79 { 0x144f, KEY_FASTFORWARD}, 82 80 { 0x145c, KEY_NEXT}, 81 + 82 + /* Terratec Black IR, with most keys in black */ 83 + { 0x04eb01, KEY_POWER2}, 84 + 85 + { 0x04eb02, KEY_1}, 86 + { 0x04eb03, KEY_2}, 87 + { 0x04eb04, KEY_3}, 88 + { 0x04eb05, KEY_4}, 89 + { 0x04eb06, KEY_5}, 90 + { 0x04eb07, KEY_6}, 91 + { 0x04eb08, KEY_7}, 92 + { 0x04eb09, KEY_8}, 93 + { 0x04eb0a, KEY_9}, 94 + { 0x04eb0c, KEY_0}, 95 + 96 + { 0x04eb0b, KEY_TEXT}, /* TXT */ 97 + { 0x04eb0d, KEY_REFRESH}, /* Refresh */ 98 + 99 + { 0x04eb0e, KEY_HOME}, 100 + { 0x04eb0f, KEY_EPG}, 101 + 102 + { 0x04eb10, KEY_UP}, 103 + { 0x04eb11, KEY_LEFT}, 104 + { 0x04eb12, KEY_OK}, 105 + { 0x04eb13, KEY_RIGHT}, 106 + { 0x04eb14, KEY_DOWN}, 107 + 108 + { 0x04eb15, KEY_BACKSPACE}, 109 + { 0x04eb16, KEY_INFO}, 110 + 111 + { 0x04eb17, KEY_RED}, 112 + { 0x04eb18, KEY_GREEN}, 113 + { 0x04eb19, KEY_YELLOW}, 114 + { 0x04eb1a, KEY_BLUE}, 115 + 116 + { 0x04eb1c, KEY_VOLUMEUP}, 117 + { 0x04eb1e, KEY_VOLUMEDOWN}, 118 + 119 + { 0x04eb1d, KEY_MUTE}, 120 + 121 + { 0x04eb1b, KEY_CHANNELUP}, 122 + { 0x04eb1f, KEY_CHANNELDOWN}, 123 + 124 + { 0x04eb40, KEY_RECORD}, 125 + { 0x04eb4c, KEY_PLAY}, 126 + { 0x04eb58, KEY_PAUSE}, 127 + 128 + { 0x04eb54, KEY_REWIND}, 129 + { 0x04eb48, KEY_STOP}, 130 + { 0x04eb5c, KEY_NEXT}, 83 131 }; 84 132 85 133 static struct rc_map_list nec_terratec_cinergy_xs_map = {
+2
drivers/media/rc/mceusb.c
··· 361 361 { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) }, 362 362 /* Formosa Industrial Computing */ 363 363 { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) }, 364 + /* Formosa Industrial Computing */ 365 + { USB_DEVICE(VENDOR_FORMOSA, 0xe042) }, 364 366 /* Fintek eHome Infrared Transceiver (HP branded) */ 365 367 { USB_DEVICE(VENDOR_FINTEK, 0x5168) }, 366 368 /* Fintek eHome Infrared Transceiver */
+1 -1
drivers/media/rc/rc-core-priv.h
··· 35 35 struct list_head list; /* to keep track of raw clients */ 36 36 struct task_struct *thread; 37 37 spinlock_t lock; 38 - struct kfifo kfifo; /* fifo for the pulse/space durations */ 38 + struct kfifo_rec_ptr_1 kfifo; /* fifo for the pulse/space durations */ 39 39 ktime_t last_event; /* when last event occurred */ 40 40 enum raw_event_type last_type; /* last event type */ 41 41 struct rc_dev *dev; /* pointer to the parent rc_dev */
+7 -2
drivers/media/rc/rc-main.c
··· 1029 1029 1030 1030 int rc_register_device(struct rc_dev *dev) 1031 1031 { 1032 + static bool raw_init = false; /* raw decoders loaded? */ 1032 1033 static atomic_t devno = ATOMIC_INIT(0); 1033 1034 struct rc_map *rc_map; 1034 1035 const char *path; ··· 1104 1103 kfree(path); 1105 1104 1106 1105 if (dev->driver_type == RC_DRIVER_IR_RAW) { 1106 + /* Load raw decoders, if they aren't already */ 1107 + if (!raw_init) { 1108 + IR_dprintk(1, "Loading raw decoders\n"); 1109 + ir_raw_init(); 1110 + raw_init = true; 1111 + } 1107 1112 rc = ir_raw_event_register(dev); 1108 1113 if (rc < 0) 1109 1114 goto out_input; ··· 1183 1176 return rc; 1184 1177 } 1185 1178 1186 - /* Initialize/load the decoders/keymap code that will be used */ 1187 - ir_raw_init(); 1188 1179 rc_map_register(&empty_map); 1189 1180 1190 1181 return 0;
+47 -2
drivers/media/video/Kconfig
··· 273 273 To compile this driver as a module, choose M here: the 274 274 module will be called adv7180. 275 275 276 + config VIDEO_ADV7183 277 + tristate "Analog Devices ADV7183 decoder" 278 + depends on VIDEO_V4L2 && I2C 279 + ---help--- 280 + V4l2 subdevice driver for the Analog Devices 281 + ADV7183 video decoder. 282 + 283 + To compile this driver as a module, choose M here: the 284 + module will be called adv7183. 285 + 276 286 config VIDEO_BT819 277 287 tristate "BT819A VideoStream decoder" 278 288 depends on VIDEO_V4L2 && I2C ··· 469 459 470 460 comment "Camera sensor devices" 471 461 462 + config VIDEO_APTINA_PLL 463 + tristate 464 + 472 465 config VIDEO_OV7670 473 466 tristate "OmniVision OV7670 sensor support" 474 467 depends on I2C && VIDEO_V4L2 ··· 480 467 OV7670 VGA camera. It currently only works with the M88ALP01 481 468 controller. 482 469 470 + config VIDEO_VS6624 471 + tristate "ST VS6624 sensor support" 472 + depends on VIDEO_V4L2 && I2C 473 + ---help--- 474 + This is a Video4Linux2 sensor-level driver for the ST VS6624 475 + camera. 476 + 477 + To compile this driver as a module, choose M here: the 478 + module will be called vs6624. 479 + 480 + config VIDEO_MT9M032 481 + tristate "MT9M032 camera sensor support" 482 + depends on I2C && VIDEO_V4L2 483 + select VIDEO_APTINA_PLL 484 + ---help--- 485 + This driver supports MT9M032 camera sensors from Aptina, monochrome 486 + models only. 487 + 483 488 config VIDEO_MT9P031 484 489 tristate "Aptina MT9P031 support" 485 490 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API 491 + select VIDEO_APTINA_PLL 486 492 ---help--- 487 493 This is a Video4Linux2 sensor-level driver for the Aptina 488 494 (Micron) mt9p031 5 Mpixel camera. ··· 883 851 884 852 source "drivers/media/video/omap/Kconfig" 885 853 854 + source "drivers/media/video/blackfin/Kconfig" 855 + 886 856 config VIDEO_SH_VOU 887 857 tristate "SuperH VOU video output driver" 888 858 depends on VIDEO_DEV && ARCH_SHMOBILE ··· 1121 1087 config VIDEO_MX2 1122 1088 tristate "i.MX27/i.MX25 Camera Sensor Interface driver" 1123 1089 depends on VIDEO_DEV && SOC_CAMERA && (MACH_MX27 || ARCH_MX25) 1124 - select VIDEOBUF_DMA_CONTIG 1090 + select VIDEOBUF2_DMA_CONTIG 1125 1091 select VIDEO_MX2_HOSTSUPPORT 1126 1092 ---help--- 1127 1093 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor ··· 1150 1116 1151 1117 config VIDEO_S5P_MIPI_CSIS 1152 1118 tristate "Samsung S5P and EXYNOS4 MIPI CSI receiver driver" 1153 - depends on VIDEO_V4L2 && PM_RUNTIME && PLAT_S5P && VIDEO_V4L2_SUBDEV_API 1119 + depends on VIDEO_V4L2 && PM_RUNTIME && PLAT_S5P 1120 + depends on VIDEO_V4L2_SUBDEV_API && REGULATOR 1154 1121 ---help--- 1155 1122 This is a v4l2 driver for Samsung S5P/EXYNOS4 MIPI-CSI receiver. 1156 1123 ··· 1210 1175 default n 1211 1176 help 1212 1177 MFC 5.1 driver for V4L2. 1178 + 1179 + config VIDEO_MX2_EMMAPRP 1180 + tristate "MX2 eMMa-PrP support" 1181 + depends on VIDEO_DEV && VIDEO_V4L2 && SOC_IMX27 1182 + select VIDEOBUF2_DMA_CONTIG 1183 + select V4L2_MEM2MEM_DEV 1184 + help 1185 + MX2X chips have a PrP that can be used to process buffers from 1186 + memory to memory. Operations include resizing and format 1187 + conversion. 1213 1188 1214 1189 endif # V4L_MEM2MEM_DRIVERS
+17 -7
drivers/media/video/Makefile
··· 12 12 13 13 videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ 14 14 v4l2-event.o v4l2-ctrls.o v4l2-subdev.o 15 + ifeq ($(CONFIG_COMPAT),y) 16 + videodev-objs += v4l2-compat-ioctl32.o 17 + endif 15 18 16 19 # V4L2 core modules 17 20 18 21 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o 19 - ifeq ($(CONFIG_COMPAT),y) 20 - obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o 21 - endif 22 - 23 22 obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o 23 + 24 + # Helper modules 25 + 26 + obj-$(CONFIG_VIDEO_APTINA_PLL) += aptina-pll.o 24 27 25 28 # All i2c modules must come first: 26 29 ··· 43 40 obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o 44 41 obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o 45 42 obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o 43 + obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o 46 44 obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o 47 45 obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o 46 + obj-$(CONFIG_VIDEO_VS6624) += vs6624.o 48 47 obj-$(CONFIG_VIDEO_BT819) += bt819.o 49 48 obj-$(CONFIG_VIDEO_BT856) += bt856.o 50 49 obj-$(CONFIG_VIDEO_BT866) += bt866.o ··· 70 65 obj-$(CONFIG_VIDEO_OV7670) += ov7670.o 71 66 obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o 72 67 obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o 68 + obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o 73 69 obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o 74 70 obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o 75 71 obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o ··· 183 177 obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o 184 178 obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o 185 179 180 + obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o 181 + 186 182 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/ 187 183 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/ 188 184 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/ 189 185 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/ 190 186 191 187 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/ 188 + 189 + obj-$(CONFIG_BLACKFIN) += blackfin/ 192 190 193 191 obj-$(CONFIG_ARCH_DAVINCI) += davinci/ 194 192 ··· 209 199 210 200 obj-$(CONFIG_ARCH_OMAP) += omap/ 211 201 212 - ccflags-y += -Idrivers/media/dvb/dvb-core 213 - ccflags-y += -Idrivers/media/dvb/frontends 214 - ccflags-y += -Idrivers/media/common/tuners 202 + ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core 203 + ccflags-y += -I$(srctree)/drivers/media/dvb/frontends 204 + ccflags-y += -I$(srctree)/drivers/media/common/tuners
+1 -19
drivers/media/video/adp1653.c
··· 33 33 #include <linux/delay.h> 34 34 #include <linux/module.h> 35 35 #include <linux/i2c.h> 36 - #include <linux/module.h> 37 36 #include <linux/slab.h> 38 37 #include <linux/version.h> 39 38 #include <media/adp1653.h> ··· 481 482 .id_table = adp1653_id_table, 482 483 }; 483 484 484 - static int __init adp1653_init(void) 485 - { 486 - int rval; 487 - 488 - rval = i2c_add_driver(&adp1653_i2c_driver); 489 - if (rval) 490 - printk(KERN_ALERT "%s: failed at i2c_add_driver\n", __func__); 491 - 492 - return rval; 493 - } 494 - 495 - static void __exit adp1653_exit(void) 496 - { 497 - i2c_del_driver(&adp1653_i2c_driver); 498 - } 499 - 500 - module_init(adp1653_init); 501 - module_exit(adp1653_exit); 485 + module_i2c_driver(adp1653_i2c_driver); 502 486 503 487 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>"); 504 488 MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver");
+1 -12
drivers/media/video/adv7170.c
··· 407 407 .id_table = adv7170_id, 408 408 }; 409 409 410 - static __init int init_adv7170(void) 411 - { 412 - return i2c_add_driver(&adv7170_driver); 413 - } 414 - 415 - static __exit void exit_adv7170(void) 416 - { 417 - i2c_del_driver(&adv7170_driver); 418 - } 419 - 420 - module_init(init_adv7170); 421 - module_exit(exit_adv7170); 410 + module_i2c_driver(adv7170_driver);
+1 -12
drivers/media/video/adv7175.c
··· 457 457 .id_table = adv7175_id, 458 458 }; 459 459 460 - static __init int init_adv7175(void) 461 - { 462 - return i2c_add_driver(&adv7175_driver); 463 - } 464 - 465 - static __exit void exit_adv7175(void) 466 - { 467 - i2c_del_driver(&adv7175_driver); 468 - } 469 - 470 - module_init(init_adv7175); 471 - module_exit(exit_adv7175); 460 + module_i2c_driver(adv7175_driver);
+1 -13
drivers/media/video/adv7180.c
··· 444 444 .id_table = adv7180_id, 445 445 }; 446 446 447 - static __init int adv7180_init(void) 448 - { 449 - return i2c_add_driver(&adv7180_driver); 450 - } 451 - 452 - static __exit void adv7180_exit(void) 453 - { 454 - i2c_del_driver(&adv7180_driver); 455 - } 456 - 457 - module_init(adv7180_init); 458 - module_exit(adv7180_exit); 447 + module_i2c_driver(adv7180_driver); 459 448 460 449 MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver"); 461 450 MODULE_AUTHOR("Mocean Laboratories"); 462 451 MODULE_LICENSE("GPL v2"); 463 -
+699
drivers/media/video/adv7183.c
··· 1 + /* 2 + * adv7183.c Analog Devices ADV7183 video decoder driver 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 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 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #include <linux/delay.h> 21 + #include <linux/errno.h> 22 + #include <linux/gpio.h> 23 + #include <linux/i2c.h> 24 + #include <linux/init.h> 25 + #include <linux/module.h> 26 + #include <linux/slab.h> 27 + #include <linux/types.h> 28 + #include <linux/videodev2.h> 29 + 30 + #include <media/adv7183.h> 31 + #include <media/v4l2-chip-ident.h> 32 + #include <media/v4l2-ctrls.h> 33 + #include <media/v4l2-device.h> 34 + 35 + #include "adv7183_regs.h" 36 + 37 + struct adv7183 { 38 + struct v4l2_subdev sd; 39 + struct v4l2_ctrl_handler hdl; 40 + 41 + v4l2_std_id std; /* Current set standard */ 42 + u32 input; 43 + u32 output; 44 + unsigned reset_pin; 45 + unsigned oe_pin; 46 + struct v4l2_mbus_framefmt fmt; 47 + }; 48 + 49 + /* EXAMPLES USING 27 MHz CLOCK 50 + * Mode 1 CVBS Input (Composite Video on AIN5) 51 + * All standards are supported through autodetect, 8-bit, 4:2:2, ITU-R BT.656 output on P15 to P8. 52 + */ 53 + static const unsigned char adv7183_init_regs[] = { 54 + ADV7183_IN_CTRL, 0x04, /* CVBS input on AIN5 */ 55 + ADV7183_DIGI_CLAMP_CTRL_1, 0x00, /* Slow down digital clamps */ 56 + ADV7183_SHAP_FILT_CTRL, 0x41, /* Set CSFM to SH1 */ 57 + ADV7183_ADC_CTRL, 0x16, /* Power down ADC 1 and ADC 2 */ 58 + ADV7183_CTI_DNR_CTRL_4, 0x04, /* Set DNR threshold to 4 for flat response */ 59 + /* ADI recommended programming sequence */ 60 + ADV7183_ADI_CTRL, 0x80, 61 + ADV7183_CTI_DNR_CTRL_4, 0x20, 62 + 0x52, 0x18, 63 + 0x58, 0xED, 64 + 0x77, 0xC5, 65 + 0x7C, 0x93, 66 + 0x7D, 0x00, 67 + 0xD0, 0x48, 68 + 0xD5, 0xA0, 69 + 0xD7, 0xEA, 70 + ADV7183_SD_SATURATION_CR, 0x3E, 71 + ADV7183_PAL_V_END, 0x3E, 72 + ADV7183_PAL_F_TOGGLE, 0x0F, 73 + ADV7183_ADI_CTRL, 0x00, 74 + }; 75 + 76 + static inline struct adv7183 *to_adv7183(struct v4l2_subdev *sd) 77 + { 78 + return container_of(sd, struct adv7183, sd); 79 + } 80 + static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) 81 + { 82 + return &container_of(ctrl->handler, struct adv7183, hdl)->sd; 83 + } 84 + 85 + static inline int adv7183_read(struct v4l2_subdev *sd, unsigned char reg) 86 + { 87 + struct i2c_client *client = v4l2_get_subdevdata(sd); 88 + 89 + return i2c_smbus_read_byte_data(client, reg); 90 + } 91 + 92 + static inline int adv7183_write(struct v4l2_subdev *sd, unsigned char reg, 93 + unsigned char value) 94 + { 95 + struct i2c_client *client = v4l2_get_subdevdata(sd); 96 + 97 + return i2c_smbus_write_byte_data(client, reg, value); 98 + } 99 + 100 + static int adv7183_writeregs(struct v4l2_subdev *sd, 101 + const unsigned char *regs, unsigned int num) 102 + { 103 + unsigned char reg, data; 104 + unsigned int cnt = 0; 105 + 106 + if (num & 0x1) { 107 + v4l2_err(sd, "invalid regs array\n"); 108 + return -1; 109 + } 110 + 111 + while (cnt < num) { 112 + reg = *regs++; 113 + data = *regs++; 114 + cnt += 2; 115 + 116 + adv7183_write(sd, reg, data); 117 + } 118 + return 0; 119 + } 120 + 121 + static int adv7183_log_status(struct v4l2_subdev *sd) 122 + { 123 + struct adv7183 *decoder = to_adv7183(sd); 124 + 125 + v4l2_info(sd, "adv7183: Input control = 0x%02x\n", 126 + adv7183_read(sd, ADV7183_IN_CTRL)); 127 + v4l2_info(sd, "adv7183: Video selection = 0x%02x\n", 128 + adv7183_read(sd, ADV7183_VD_SEL)); 129 + v4l2_info(sd, "adv7183: Output control = 0x%02x\n", 130 + adv7183_read(sd, ADV7183_OUT_CTRL)); 131 + v4l2_info(sd, "adv7183: Extended output control = 0x%02x\n", 132 + adv7183_read(sd, ADV7183_EXT_OUT_CTRL)); 133 + v4l2_info(sd, "adv7183: Autodetect enable = 0x%02x\n", 134 + adv7183_read(sd, ADV7183_AUTO_DET_EN)); 135 + v4l2_info(sd, "adv7183: Contrast = 0x%02x\n", 136 + adv7183_read(sd, ADV7183_CONTRAST)); 137 + v4l2_info(sd, "adv7183: Brightness = 0x%02x\n", 138 + adv7183_read(sd, ADV7183_BRIGHTNESS)); 139 + v4l2_info(sd, "adv7183: Hue = 0x%02x\n", 140 + adv7183_read(sd, ADV7183_HUE)); 141 + v4l2_info(sd, "adv7183: Default value Y = 0x%02x\n", 142 + adv7183_read(sd, ADV7183_DEF_Y)); 143 + v4l2_info(sd, "adv7183: Default value C = 0x%02x\n", 144 + adv7183_read(sd, ADV7183_DEF_C)); 145 + v4l2_info(sd, "adv7183: ADI control = 0x%02x\n", 146 + adv7183_read(sd, ADV7183_ADI_CTRL)); 147 + v4l2_info(sd, "adv7183: Power Management = 0x%02x\n", 148 + adv7183_read(sd, ADV7183_POW_MANAGE)); 149 + v4l2_info(sd, "adv7183: Status 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n", 150 + adv7183_read(sd, ADV7183_STATUS_1), 151 + adv7183_read(sd, ADV7183_STATUS_2), 152 + adv7183_read(sd, ADV7183_STATUS_3)); 153 + v4l2_info(sd, "adv7183: Ident = 0x%02x\n", 154 + adv7183_read(sd, ADV7183_IDENT)); 155 + v4l2_info(sd, "adv7183: Analog clamp control = 0x%02x\n", 156 + adv7183_read(sd, ADV7183_ANAL_CLAMP_CTRL)); 157 + v4l2_info(sd, "adv7183: Digital clamp control 1 = 0x%02x\n", 158 + adv7183_read(sd, ADV7183_DIGI_CLAMP_CTRL_1)); 159 + v4l2_info(sd, "adv7183: Shaping filter control 1 and 2 = 0x%02x 0x%02x\n", 160 + adv7183_read(sd, ADV7183_SHAP_FILT_CTRL), 161 + adv7183_read(sd, ADV7183_SHAP_FILT_CTRL_2)); 162 + v4l2_info(sd, "adv7183: Comb filter control = 0x%02x\n", 163 + adv7183_read(sd, ADV7183_COMB_FILT_CTRL)); 164 + v4l2_info(sd, "adv7183: ADI control 2 = 0x%02x\n", 165 + adv7183_read(sd, ADV7183_ADI_CTRL_2)); 166 + v4l2_info(sd, "adv7183: Pixel delay control = 0x%02x\n", 167 + adv7183_read(sd, ADV7183_PIX_DELAY_CTRL)); 168 + v4l2_info(sd, "adv7183: Misc gain control = 0x%02x\n", 169 + adv7183_read(sd, ADV7183_MISC_GAIN_CTRL)); 170 + v4l2_info(sd, "adv7183: AGC mode control = 0x%02x\n", 171 + adv7183_read(sd, ADV7183_AGC_MODE_CTRL)); 172 + v4l2_info(sd, "adv7183: Chroma gain control 1 and 2 = 0x%02x 0x%02x\n", 173 + adv7183_read(sd, ADV7183_CHRO_GAIN_CTRL_1), 174 + adv7183_read(sd, ADV7183_CHRO_GAIN_CTRL_2)); 175 + v4l2_info(sd, "adv7183: Luma gain control 1 and 2 = 0x%02x 0x%02x\n", 176 + adv7183_read(sd, ADV7183_LUMA_GAIN_CTRL_1), 177 + adv7183_read(sd, ADV7183_LUMA_GAIN_CTRL_2)); 178 + v4l2_info(sd, "adv7183: Vsync field control 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n", 179 + adv7183_read(sd, ADV7183_VS_FIELD_CTRL_1), 180 + adv7183_read(sd, ADV7183_VS_FIELD_CTRL_2), 181 + adv7183_read(sd, ADV7183_VS_FIELD_CTRL_3)); 182 + v4l2_info(sd, "adv7183: Hsync positon control 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n", 183 + adv7183_read(sd, ADV7183_HS_POS_CTRL_1), 184 + adv7183_read(sd, ADV7183_HS_POS_CTRL_2), 185 + adv7183_read(sd, ADV7183_HS_POS_CTRL_3)); 186 + v4l2_info(sd, "adv7183: Polarity = 0x%02x\n", 187 + adv7183_read(sd, ADV7183_POLARITY)); 188 + v4l2_info(sd, "adv7183: ADC control = 0x%02x\n", 189 + adv7183_read(sd, ADV7183_ADC_CTRL)); 190 + v4l2_info(sd, "adv7183: SD offset Cb and Cr = 0x%02x 0x%02x\n", 191 + adv7183_read(sd, ADV7183_SD_OFFSET_CB), 192 + adv7183_read(sd, ADV7183_SD_OFFSET_CR)); 193 + v4l2_info(sd, "adv7183: SD saturation Cb and Cr = 0x%02x 0x%02x\n", 194 + adv7183_read(sd, ADV7183_SD_SATURATION_CB), 195 + adv7183_read(sd, ADV7183_SD_SATURATION_CR)); 196 + v4l2_info(sd, "adv7183: Drive strength = 0x%02x\n", 197 + adv7183_read(sd, ADV7183_DRIVE_STR)); 198 + v4l2_ctrl_handler_log_status(&decoder->hdl, sd->name); 199 + return 0; 200 + } 201 + 202 + static int adv7183_g_std(struct v4l2_subdev *sd, v4l2_std_id *std) 203 + { 204 + struct adv7183 *decoder = to_adv7183(sd); 205 + 206 + *std = decoder->std; 207 + return 0; 208 + } 209 + 210 + static int adv7183_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 211 + { 212 + struct adv7183 *decoder = to_adv7183(sd); 213 + int reg; 214 + 215 + reg = adv7183_read(sd, ADV7183_IN_CTRL) & 0xF; 216 + if (std == V4L2_STD_PAL_60) 217 + reg |= 0x60; 218 + else if (std == V4L2_STD_NTSC_443) 219 + reg |= 0x70; 220 + else if (std == V4L2_STD_PAL_N) 221 + reg |= 0x90; 222 + else if (std == V4L2_STD_PAL_M) 223 + reg |= 0xA0; 224 + else if (std == V4L2_STD_PAL_Nc) 225 + reg |= 0xC0; 226 + else if (std & V4L2_STD_PAL) 227 + reg |= 0x80; 228 + else if (std & V4L2_STD_NTSC) 229 + reg |= 0x50; 230 + else if (std & V4L2_STD_SECAM) 231 + reg |= 0xE0; 232 + else 233 + return -EINVAL; 234 + adv7183_write(sd, ADV7183_IN_CTRL, reg); 235 + 236 + decoder->std = std; 237 + 238 + return 0; 239 + } 240 + 241 + static int adv7183_reset(struct v4l2_subdev *sd, u32 val) 242 + { 243 + int reg; 244 + 245 + reg = adv7183_read(sd, ADV7183_POW_MANAGE) | 0x80; 246 + adv7183_write(sd, ADV7183_POW_MANAGE, reg); 247 + /* wait 5ms before any further i2c writes are performed */ 248 + usleep_range(5000, 10000); 249 + return 0; 250 + } 251 + 252 + static int adv7183_s_routing(struct v4l2_subdev *sd, 253 + u32 input, u32 output, u32 config) 254 + { 255 + struct adv7183 *decoder = to_adv7183(sd); 256 + int reg; 257 + 258 + if ((input > ADV7183_COMPONENT1) || (output > ADV7183_16BIT_OUT)) 259 + return -EINVAL; 260 + 261 + if (input != decoder->input) { 262 + decoder->input = input; 263 + reg = adv7183_read(sd, ADV7183_IN_CTRL) & 0xF0; 264 + switch (input) { 265 + case ADV7183_COMPOSITE1: 266 + reg |= 0x1; 267 + break; 268 + case ADV7183_COMPOSITE2: 269 + reg |= 0x2; 270 + break; 271 + case ADV7183_COMPOSITE3: 272 + reg |= 0x3; 273 + break; 274 + case ADV7183_COMPOSITE4: 275 + reg |= 0x4; 276 + break; 277 + case ADV7183_COMPOSITE5: 278 + reg |= 0x5; 279 + break; 280 + case ADV7183_COMPOSITE6: 281 + reg |= 0xB; 282 + break; 283 + case ADV7183_COMPOSITE7: 284 + reg |= 0xC; 285 + break; 286 + case ADV7183_COMPOSITE8: 287 + reg |= 0xD; 288 + break; 289 + case ADV7183_COMPOSITE9: 290 + reg |= 0xE; 291 + break; 292 + case ADV7183_COMPOSITE10: 293 + reg |= 0xF; 294 + break; 295 + case ADV7183_SVIDEO0: 296 + reg |= 0x6; 297 + break; 298 + case ADV7183_SVIDEO1: 299 + reg |= 0x7; 300 + break; 301 + case ADV7183_SVIDEO2: 302 + reg |= 0x8; 303 + break; 304 + case ADV7183_COMPONENT0: 305 + reg |= 0x9; 306 + break; 307 + case ADV7183_COMPONENT1: 308 + reg |= 0xA; 309 + break; 310 + default: 311 + break; 312 + } 313 + adv7183_write(sd, ADV7183_IN_CTRL, reg); 314 + } 315 + 316 + if (output != decoder->output) { 317 + decoder->output = output; 318 + reg = adv7183_read(sd, ADV7183_OUT_CTRL) & 0xC0; 319 + switch (output) { 320 + case ADV7183_16BIT_OUT: 321 + reg |= 0x9; 322 + break; 323 + default: 324 + reg |= 0xC; 325 + break; 326 + } 327 + adv7183_write(sd, ADV7183_OUT_CTRL, reg); 328 + } 329 + 330 + return 0; 331 + } 332 + 333 + static int adv7183_s_ctrl(struct v4l2_ctrl *ctrl) 334 + { 335 + struct v4l2_subdev *sd = to_sd(ctrl); 336 + int val = ctrl->val; 337 + 338 + switch (ctrl->id) { 339 + case V4L2_CID_BRIGHTNESS: 340 + if (val < 0) 341 + val = 127 - val; 342 + adv7183_write(sd, ADV7183_BRIGHTNESS, val); 343 + break; 344 + case V4L2_CID_CONTRAST: 345 + adv7183_write(sd, ADV7183_CONTRAST, val); 346 + break; 347 + case V4L2_CID_SATURATION: 348 + adv7183_write(sd, ADV7183_SD_SATURATION_CB, val >> 8); 349 + adv7183_write(sd, ADV7183_SD_SATURATION_CR, (val & 0xFF)); 350 + break; 351 + case V4L2_CID_HUE: 352 + adv7183_write(sd, ADV7183_SD_OFFSET_CB, val >> 8); 353 + adv7183_write(sd, ADV7183_SD_OFFSET_CR, (val & 0xFF)); 354 + break; 355 + default: 356 + return -EINVAL; 357 + } 358 + 359 + return 0; 360 + } 361 + 362 + static int adv7183_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) 363 + { 364 + struct adv7183 *decoder = to_adv7183(sd); 365 + int reg; 366 + 367 + /* enable autodetection block */ 368 + reg = adv7183_read(sd, ADV7183_IN_CTRL) & 0xF; 369 + adv7183_write(sd, ADV7183_IN_CTRL, reg); 370 + 371 + /* wait autodetection switch */ 372 + mdelay(10); 373 + 374 + /* get autodetection result */ 375 + reg = adv7183_read(sd, ADV7183_STATUS_1); 376 + switch ((reg >> 0x4) & 0x7) { 377 + case 0: 378 + *std = V4L2_STD_NTSC; 379 + break; 380 + case 1: 381 + *std = V4L2_STD_NTSC_443; 382 + break; 383 + case 2: 384 + *std = V4L2_STD_PAL_M; 385 + break; 386 + case 3: 387 + *std = V4L2_STD_PAL_60; 388 + break; 389 + case 4: 390 + *std = V4L2_STD_PAL; 391 + break; 392 + case 5: 393 + *std = V4L2_STD_SECAM; 394 + break; 395 + case 6: 396 + *std = V4L2_STD_PAL_Nc; 397 + break; 398 + case 7: 399 + *std = V4L2_STD_SECAM; 400 + break; 401 + default: 402 + *std = V4L2_STD_UNKNOWN; 403 + break; 404 + } 405 + 406 + /* after std detection, write back user set std */ 407 + adv7183_s_std(sd, decoder->std); 408 + return 0; 409 + } 410 + 411 + static int adv7183_g_input_status(struct v4l2_subdev *sd, u32 *status) 412 + { 413 + int reg; 414 + 415 + *status = V4L2_IN_ST_NO_SIGNAL; 416 + reg = adv7183_read(sd, ADV7183_STATUS_1); 417 + if (reg < 0) 418 + return reg; 419 + if (reg & 0x1) 420 + *status = 0; 421 + return 0; 422 + } 423 + 424 + static int adv7183_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, 425 + enum v4l2_mbus_pixelcode *code) 426 + { 427 + if (index > 0) 428 + return -EINVAL; 429 + 430 + *code = V4L2_MBUS_FMT_UYVY8_2X8; 431 + return 0; 432 + } 433 + 434 + static int adv7183_try_mbus_fmt(struct v4l2_subdev *sd, 435 + struct v4l2_mbus_framefmt *fmt) 436 + { 437 + struct adv7183 *decoder = to_adv7183(sd); 438 + 439 + fmt->code = V4L2_MBUS_FMT_UYVY8_2X8; 440 + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; 441 + if (decoder->std & V4L2_STD_525_60) { 442 + fmt->field = V4L2_FIELD_SEQ_TB; 443 + fmt->width = 720; 444 + fmt->height = 480; 445 + } else { 446 + fmt->field = V4L2_FIELD_SEQ_BT; 447 + fmt->width = 720; 448 + fmt->height = 576; 449 + } 450 + return 0; 451 + } 452 + 453 + static int adv7183_s_mbus_fmt(struct v4l2_subdev *sd, 454 + struct v4l2_mbus_framefmt *fmt) 455 + { 456 + struct adv7183 *decoder = to_adv7183(sd); 457 + 458 + adv7183_try_mbus_fmt(sd, fmt); 459 + decoder->fmt = *fmt; 460 + return 0; 461 + } 462 + 463 + static int adv7183_g_mbus_fmt(struct v4l2_subdev *sd, 464 + struct v4l2_mbus_framefmt *fmt) 465 + { 466 + struct adv7183 *decoder = to_adv7183(sd); 467 + 468 + *fmt = decoder->fmt; 469 + return 0; 470 + } 471 + 472 + static int adv7183_s_stream(struct v4l2_subdev *sd, int enable) 473 + { 474 + struct adv7183 *decoder = to_adv7183(sd); 475 + 476 + if (enable) 477 + gpio_direction_output(decoder->oe_pin, 0); 478 + else 479 + gpio_direction_output(decoder->oe_pin, 1); 480 + udelay(1); 481 + return 0; 482 + } 483 + 484 + static int adv7183_g_chip_ident(struct v4l2_subdev *sd, 485 + struct v4l2_dbg_chip_ident *chip) 486 + { 487 + int rev; 488 + struct i2c_client *client = v4l2_get_subdevdata(sd); 489 + 490 + /* 0x11 for adv7183, 0x13 for adv7183b */ 491 + rev = adv7183_read(sd, ADV7183_IDENT); 492 + 493 + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7183, rev); 494 + } 495 + 496 + #ifdef CONFIG_VIDEO_ADV_DEBUG 497 + static int adv7183_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) 498 + { 499 + struct i2c_client *client = v4l2_get_subdevdata(sd); 500 + 501 + if (!v4l2_chip_match_i2c_client(client, &reg->match)) 502 + return -EINVAL; 503 + if (!capable(CAP_SYS_ADMIN)) 504 + return -EPERM; 505 + reg->val = adv7183_read(sd, reg->reg & 0xff); 506 + reg->size = 1; 507 + return 0; 508 + } 509 + 510 + static int adv7183_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) 511 + { 512 + struct i2c_client *client = v4l2_get_subdevdata(sd); 513 + 514 + if (!v4l2_chip_match_i2c_client(client, &reg->match)) 515 + return -EINVAL; 516 + if (!capable(CAP_SYS_ADMIN)) 517 + return -EPERM; 518 + adv7183_write(sd, reg->reg & 0xff, reg->val & 0xff); 519 + return 0; 520 + } 521 + #endif 522 + 523 + static const struct v4l2_ctrl_ops adv7183_ctrl_ops = { 524 + .s_ctrl = adv7183_s_ctrl, 525 + }; 526 + 527 + static const struct v4l2_subdev_core_ops adv7183_core_ops = { 528 + .log_status = adv7183_log_status, 529 + .g_std = adv7183_g_std, 530 + .s_std = adv7183_s_std, 531 + .reset = adv7183_reset, 532 + .g_chip_ident = adv7183_g_chip_ident, 533 + #ifdef CONFIG_VIDEO_ADV_DEBUG 534 + .g_register = adv7183_g_register, 535 + .s_register = adv7183_s_register, 536 + #endif 537 + }; 538 + 539 + static const struct v4l2_subdev_video_ops adv7183_video_ops = { 540 + .s_routing = adv7183_s_routing, 541 + .querystd = adv7183_querystd, 542 + .g_input_status = adv7183_g_input_status, 543 + .enum_mbus_fmt = adv7183_enum_mbus_fmt, 544 + .try_mbus_fmt = adv7183_try_mbus_fmt, 545 + .s_mbus_fmt = adv7183_s_mbus_fmt, 546 + .g_mbus_fmt = adv7183_g_mbus_fmt, 547 + .s_stream = adv7183_s_stream, 548 + }; 549 + 550 + static const struct v4l2_subdev_ops adv7183_ops = { 551 + .core = &adv7183_core_ops, 552 + .video = &adv7183_video_ops, 553 + }; 554 + 555 + static int adv7183_probe(struct i2c_client *client, 556 + const struct i2c_device_id *id) 557 + { 558 + struct adv7183 *decoder; 559 + struct v4l2_subdev *sd; 560 + struct v4l2_ctrl_handler *hdl; 561 + int ret; 562 + struct v4l2_mbus_framefmt fmt; 563 + const unsigned *pin_array; 564 + 565 + /* Check if the adapter supports the needed features */ 566 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 567 + return -EIO; 568 + 569 + v4l_info(client, "chip found @ 0x%02x (%s)\n", 570 + client->addr << 1, client->adapter->name); 571 + 572 + pin_array = client->dev.platform_data; 573 + if (pin_array == NULL) 574 + return -EINVAL; 575 + 576 + decoder = kzalloc(sizeof(struct adv7183), GFP_KERNEL); 577 + if (decoder == NULL) 578 + return -ENOMEM; 579 + 580 + decoder->reset_pin = pin_array[0]; 581 + decoder->oe_pin = pin_array[1]; 582 + 583 + if (gpio_request(decoder->reset_pin, "ADV7183 Reset")) { 584 + v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin); 585 + ret = -EBUSY; 586 + goto err_free_decoder; 587 + } 588 + 589 + if (gpio_request(decoder->oe_pin, "ADV7183 Output Enable")) { 590 + v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin); 591 + ret = -EBUSY; 592 + goto err_free_reset; 593 + } 594 + 595 + sd = &decoder->sd; 596 + v4l2_i2c_subdev_init(sd, client, &adv7183_ops); 597 + 598 + hdl = &decoder->hdl; 599 + v4l2_ctrl_handler_init(hdl, 4); 600 + v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops, 601 + V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); 602 + v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops, 603 + V4L2_CID_CONTRAST, 0, 0xFF, 1, 0x80); 604 + v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops, 605 + V4L2_CID_SATURATION, 0, 0xFFFF, 1, 0x8080); 606 + v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops, 607 + V4L2_CID_HUE, 0, 0xFFFF, 1, 0x8080); 608 + /* hook the control handler into the driver */ 609 + sd->ctrl_handler = hdl; 610 + if (hdl->error) { 611 + ret = hdl->error; 612 + 613 + v4l2_ctrl_handler_free(hdl); 614 + goto err_free_oe; 615 + } 616 + 617 + /* v4l2 doesn't support an autodetect standard, pick PAL as default */ 618 + decoder->std = V4L2_STD_PAL; 619 + decoder->input = ADV7183_COMPOSITE4; 620 + decoder->output = ADV7183_8BIT_OUT; 621 + 622 + gpio_direction_output(decoder->oe_pin, 1); 623 + /* reset chip */ 624 + gpio_direction_output(decoder->reset_pin, 0); 625 + /* reset pulse width at least 5ms */ 626 + mdelay(10); 627 + gpio_direction_output(decoder->reset_pin, 1); 628 + /* wait 5ms before any further i2c writes are performed */ 629 + mdelay(5); 630 + 631 + adv7183_writeregs(sd, adv7183_init_regs, ARRAY_SIZE(adv7183_init_regs)); 632 + adv7183_s_std(sd, decoder->std); 633 + fmt.width = 720; 634 + fmt.height = 576; 635 + adv7183_s_mbus_fmt(sd, &fmt); 636 + 637 + /* initialize the hardware to the default control values */ 638 + ret = v4l2_ctrl_handler_setup(hdl); 639 + if (ret) { 640 + v4l2_ctrl_handler_free(hdl); 641 + goto err_free_oe; 642 + } 643 + 644 + return 0; 645 + err_free_oe: 646 + gpio_free(decoder->oe_pin); 647 + err_free_reset: 648 + gpio_free(decoder->reset_pin); 649 + err_free_decoder: 650 + kfree(decoder); 651 + return ret; 652 + } 653 + 654 + static int adv7183_remove(struct i2c_client *client) 655 + { 656 + struct v4l2_subdev *sd = i2c_get_clientdata(client); 657 + struct adv7183 *decoder = to_adv7183(sd); 658 + 659 + v4l2_device_unregister_subdev(sd); 660 + v4l2_ctrl_handler_free(sd->ctrl_handler); 661 + gpio_free(decoder->oe_pin); 662 + gpio_free(decoder->reset_pin); 663 + kfree(decoder); 664 + return 0; 665 + } 666 + 667 + static const struct i2c_device_id adv7183_id[] = { 668 + {"adv7183", 0}, 669 + {}, 670 + }; 671 + 672 + MODULE_DEVICE_TABLE(i2c, adv7183_id); 673 + 674 + static struct i2c_driver adv7183_driver = { 675 + .driver = { 676 + .owner = THIS_MODULE, 677 + .name = "adv7183", 678 + }, 679 + .probe = adv7183_probe, 680 + .remove = __devexit_p(adv7183_remove), 681 + .id_table = adv7183_id, 682 + }; 683 + 684 + static __init int adv7183_init(void) 685 + { 686 + return i2c_add_driver(&adv7183_driver); 687 + } 688 + 689 + static __exit void adv7183_exit(void) 690 + { 691 + i2c_del_driver(&adv7183_driver); 692 + } 693 + 694 + module_init(adv7183_init); 695 + module_exit(adv7183_exit); 696 + 697 + MODULE_DESCRIPTION("Analog Devices ADV7183 video decoder driver"); 698 + MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>"); 699 + MODULE_LICENSE("GPL v2");
+107
drivers/media/video/adv7183_regs.h
··· 1 + /* 2 + * adv7183 - Analog Devices ADV7183 video decoder registers 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 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 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #ifndef _ADV7183_REGS_H_ 21 + #define _ADV7183_REGS_H_ 22 + 23 + #define ADV7183_IN_CTRL 0x00 /* Input control */ 24 + #define ADV7183_VD_SEL 0x01 /* Video selection */ 25 + #define ADV7183_OUT_CTRL 0x03 /* Output control */ 26 + #define ADV7183_EXT_OUT_CTRL 0x04 /* Extended output control */ 27 + #define ADV7183_AUTO_DET_EN 0x07 /* Autodetect enable */ 28 + #define ADV7183_CONTRAST 0x08 /* Contrast */ 29 + #define ADV7183_BRIGHTNESS 0x0A /* Brightness */ 30 + #define ADV7183_HUE 0x0B /* Hue */ 31 + #define ADV7183_DEF_Y 0x0C /* Default value Y */ 32 + #define ADV7183_DEF_C 0x0D /* Default value C */ 33 + #define ADV7183_ADI_CTRL 0x0E /* ADI control */ 34 + #define ADV7183_POW_MANAGE 0x0F /* Power Management */ 35 + #define ADV7183_STATUS_1 0x10 /* Status 1 */ 36 + #define ADV7183_IDENT 0x11 /* Ident */ 37 + #define ADV7183_STATUS_2 0x12 /* Status 2 */ 38 + #define ADV7183_STATUS_3 0x13 /* Status 3 */ 39 + #define ADV7183_ANAL_CLAMP_CTRL 0x14 /* Analog clamp control */ 40 + #define ADV7183_DIGI_CLAMP_CTRL_1 0x15 /* Digital clamp control 1 */ 41 + #define ADV7183_SHAP_FILT_CTRL 0x17 /* Shaping filter control */ 42 + #define ADV7183_SHAP_FILT_CTRL_2 0x18 /* Shaping filter control 2 */ 43 + #define ADV7183_COMB_FILT_CTRL 0x19 /* Comb filter control */ 44 + #define ADV7183_ADI_CTRL_2 0x1D /* ADI control 2 */ 45 + #define ADV7183_PIX_DELAY_CTRL 0x27 /* Pixel delay control */ 46 + #define ADV7183_MISC_GAIN_CTRL 0x2B /* Misc gain control */ 47 + #define ADV7183_AGC_MODE_CTRL 0x2C /* AGC mode control */ 48 + #define ADV7183_CHRO_GAIN_CTRL_1 0x2D /* Chroma gain control 1 */ 49 + #define ADV7183_CHRO_GAIN_CTRL_2 0x2E /* Chroma gain control 2 */ 50 + #define ADV7183_LUMA_GAIN_CTRL_1 0x2F /* Luma gain control 1 */ 51 + #define ADV7183_LUMA_GAIN_CTRL_2 0x30 /* Luma gain control 2 */ 52 + #define ADV7183_VS_FIELD_CTRL_1 0x31 /* Vsync field control 1 */ 53 + #define ADV7183_VS_FIELD_CTRL_2 0x32 /* Vsync field control 2 */ 54 + #define ADV7183_VS_FIELD_CTRL_3 0x33 /* Vsync field control 3 */ 55 + #define ADV7183_HS_POS_CTRL_1 0x34 /* Hsync positon control 1 */ 56 + #define ADV7183_HS_POS_CTRL_2 0x35 /* Hsync positon control 2 */ 57 + #define ADV7183_HS_POS_CTRL_3 0x36 /* Hsync positon control 3 */ 58 + #define ADV7183_POLARITY 0x37 /* Polarity */ 59 + #define ADV7183_NTSC_COMB_CTRL 0x38 /* NTSC comb control */ 60 + #define ADV7183_PAL_COMB_CTRL 0x39 /* PAL comb control */ 61 + #define ADV7183_ADC_CTRL 0x3A /* ADC control */ 62 + #define ADV7183_MAN_WIN_CTRL 0x3D /* Manual window control */ 63 + #define ADV7183_RESAMPLE_CTRL 0x41 /* Resample control */ 64 + #define ADV7183_GEMSTAR_CTRL_1 0x48 /* Gemstar ctrl 1 */ 65 + #define ADV7183_GEMSTAR_CTRL_2 0x49 /* Gemstar ctrl 2 */ 66 + #define ADV7183_GEMSTAR_CTRL_3 0x4A /* Gemstar ctrl 3 */ 67 + #define ADV7183_GEMSTAR_CTRL_4 0x4B /* Gemstar ctrl 4 */ 68 + #define ADV7183_GEMSTAR_CTRL_5 0x4C /* Gemstar ctrl 5 */ 69 + #define ADV7183_CTI_DNR_CTRL_1 0x4D /* CTI DNR ctrl 1 */ 70 + #define ADV7183_CTI_DNR_CTRL_2 0x4E /* CTI DNR ctrl 2 */ 71 + #define ADV7183_CTI_DNR_CTRL_4 0x50 /* CTI DNR ctrl 4 */ 72 + #define ADV7183_LOCK_CNT 0x51 /* Lock count */ 73 + #define ADV7183_FREE_LINE_LEN 0x8F /* Free-Run line length 1 */ 74 + #define ADV7183_VBI_INFO 0x90 /* VBI info */ 75 + #define ADV7183_WSS_1 0x91 /* WSS 1 */ 76 + #define ADV7183_WSS_2 0x92 /* WSS 2 */ 77 + #define ADV7183_EDTV_1 0x93 /* EDTV 1 */ 78 + #define ADV7183_EDTV_2 0x94 /* EDTV 2 */ 79 + #define ADV7183_EDTV_3 0x95 /* EDTV 3 */ 80 + #define ADV7183_CGMS_1 0x96 /* CGMS 1 */ 81 + #define ADV7183_CGMS_2 0x97 /* CGMS 2 */ 82 + #define ADV7183_CGMS_3 0x98 /* CGMS 3 */ 83 + #define ADV7183_CCAP_1 0x99 /* CCAP 1 */ 84 + #define ADV7183_CCAP_2 0x9A /* CCAP 2 */ 85 + #define ADV7183_LETTERBOX_1 0x9B /* Letterbox 1 */ 86 + #define ADV7183_LETTERBOX_2 0x9C /* Letterbox 2 */ 87 + #define ADV7183_LETTERBOX_3 0x9D /* Letterbox 3 */ 88 + #define ADV7183_CRC_EN 0xB2 /* CRC enable */ 89 + #define ADV7183_ADC_SWITCH_1 0xC3 /* ADC switch 1 */ 90 + #define ADV7183_ADC_SWITCH_2 0xC4 /* ADC swithc 2 */ 91 + #define ADV7183_LETTERBOX_CTRL_1 0xDC /* Letterbox control 1 */ 92 + #define ADV7183_LETTERBOX_CTRL_2 0xDD /* Letterbox control 2 */ 93 + #define ADV7183_SD_OFFSET_CB 0xE1 /* SD offset Cb */ 94 + #define ADV7183_SD_OFFSET_CR 0xE2 /* SD offset Cr */ 95 + #define ADV7183_SD_SATURATION_CB 0xE3 /* SD saturation Cb */ 96 + #define ADV7183_SD_SATURATION_CR 0xE4 /* SD saturation Cr */ 97 + #define ADV7183_NTSC_V_BEGIN 0xE5 /* NTSC V bit begin */ 98 + #define ADV7183_NTSC_V_END 0xE6 /* NTSC V bit end */ 99 + #define ADV7183_NTSC_F_TOGGLE 0xE7 /* NTSC F bit toggle */ 100 + #define ADV7183_PAL_V_BEGIN 0xE8 /* PAL V bit begin */ 101 + #define ADV7183_PAL_V_END 0xE9 /* PAL V bit end */ 102 + #define ADV7183_PAL_F_TOGGLE 0xEA /* PAL F bit toggle */ 103 + #define ADV7183_DRIVE_STR 0xF4 /* Drive strength */ 104 + #define ADV7183_IF_COMP_CTRL 0xF8 /* IF comp control */ 105 + #define ADV7183_VS_MODE_CTRL 0xF9 /* VS mode control */ 106 + 107 + #endif
+1 -12
drivers/media/video/adv7343.c
··· 475 475 .id_table = adv7343_id, 476 476 }; 477 477 478 - static __init int init_adv7343(void) 479 - { 480 - return i2c_add_driver(&adv7343_driver); 481 - } 482 - 483 - static __exit void exit_adv7343(void) 484 - { 485 - i2c_del_driver(&adv7343_driver); 486 - } 487 - 488 - module_init(init_adv7343); 489 - module_exit(exit_adv7343); 478 + module_i2c_driver(adv7343_driver);
+1 -12
drivers/media/video/ak881x.c
··· 352 352 .id_table = ak881x_id, 353 353 }; 354 354 355 - static int __init ak881x_module_init(void) 356 - { 357 - return i2c_add_driver(&ak881x_i2c_driver); 358 - } 359 - 360 - static void __exit ak881x_module_exit(void) 361 - { 362 - i2c_del_driver(&ak881x_i2c_driver); 363 - } 364 - 365 - module_init(ak881x_module_init); 366 - module_exit(ak881x_module_exit); 355 + module_i2c_driver(ak881x_i2c_driver); 367 356 368 357 MODULE_DESCRIPTION("TV-output driver for ak8813/ak8814"); 369 358 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+174
drivers/media/video/aptina-pll.c
··· 1 + /* 2 + * Aptina Sensor PLL Configuration 3 + * 4 + * Copyright (C) 2012 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 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 8 + * version 2 as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, but 11 + * WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 + * General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 + * 02110-1301 USA 19 + */ 20 + 21 + #include <linux/device.h> 22 + #include <linux/gcd.h> 23 + #include <linux/kernel.h> 24 + #include <linux/lcm.h> 25 + #include <linux/module.h> 26 + 27 + #include "aptina-pll.h" 28 + 29 + int aptina_pll_calculate(struct device *dev, 30 + const struct aptina_pll_limits *limits, 31 + struct aptina_pll *pll) 32 + { 33 + unsigned int mf_min; 34 + unsigned int mf_max; 35 + unsigned int p1_min; 36 + unsigned int p1_max; 37 + unsigned int p1; 38 + unsigned int div; 39 + 40 + dev_dbg(dev, "PLL: ext clock %u pix clock %u\n", 41 + pll->ext_clock, pll->pix_clock); 42 + 43 + if (pll->ext_clock < limits->ext_clock_min || 44 + pll->ext_clock > limits->ext_clock_max) { 45 + dev_err(dev, "pll: invalid external clock frequency.\n"); 46 + return -EINVAL; 47 + } 48 + 49 + if (pll->pix_clock == 0 || pll->pix_clock > limits->pix_clock_max) { 50 + dev_err(dev, "pll: invalid pixel clock frequency.\n"); 51 + return -EINVAL; 52 + } 53 + 54 + /* Compute the multiplier M and combined N*P1 divisor. */ 55 + div = gcd(pll->pix_clock, pll->ext_clock); 56 + pll->m = pll->pix_clock / div; 57 + div = pll->ext_clock / div; 58 + 59 + /* We now have the smallest M and N*P1 values that will result in the 60 + * desired pixel clock frequency, but they might be out of the valid 61 + * range. Compute the factor by which we should multiply them given the 62 + * following constraints: 63 + * 64 + * - minimum/maximum multiplier 65 + * - minimum/maximum multiplier output clock frequency assuming the 66 + * minimum/maximum N value 67 + * - minimum/maximum combined N*P1 divisor 68 + */ 69 + mf_min = DIV_ROUND_UP(limits->m_min, pll->m); 70 + mf_min = max(mf_min, limits->out_clock_min / 71 + (pll->ext_clock / limits->n_min * pll->m)); 72 + mf_min = max(mf_min, limits->n_min * limits->p1_min / div); 73 + mf_max = limits->m_max / pll->m; 74 + mf_max = min(mf_max, limits->out_clock_max / 75 + (pll->ext_clock / limits->n_max * pll->m)); 76 + mf_max = min(mf_max, DIV_ROUND_UP(limits->n_max * limits->p1_max, div)); 77 + 78 + dev_dbg(dev, "pll: mf min %u max %u\n", mf_min, mf_max); 79 + if (mf_min > mf_max) { 80 + dev_err(dev, "pll: no valid combined N*P1 divisor.\n"); 81 + return -EINVAL; 82 + } 83 + 84 + /* 85 + * We're looking for the highest acceptable P1 value for which a 86 + * multiplier factor MF exists that fulfills the following conditions: 87 + * 88 + * 1. p1 is in the [p1_min, p1_max] range given by the limits and is 89 + * even 90 + * 2. mf is in the [mf_min, mf_max] range computed above 91 + * 3. div * mf is a multiple of p1, in order to compute 92 + * n = div * mf / p1 93 + * m = pll->m * mf 94 + * 4. the internal clock frequency, given by ext_clock / n, is in the 95 + * [int_clock_min, int_clock_max] range given by the limits 96 + * 5. the output clock frequency, given by ext_clock / n * m, is in the 97 + * [out_clock_min, out_clock_max] range given by the limits 98 + * 99 + * The first naive approach is to iterate over all p1 values acceptable 100 + * according to (1) and all mf values acceptable according to (2), and 101 + * stop at the first combination that fulfills (3), (4) and (5). This 102 + * has a O(n^2) complexity. 103 + * 104 + * Instead of iterating over all mf values in the [mf_min, mf_max] range 105 + * we can compute the mf increment between two acceptable values 106 + * according to (3) with 107 + * 108 + * mf_inc = p1 / gcd(div, p1) (6) 109 + * 110 + * and round the minimum up to the nearest multiple of mf_inc. This will 111 + * restrict the number of mf values to be checked. 112 + * 113 + * Furthermore, conditions (4) and (5) only restrict the range of 114 + * acceptable p1 and mf values by modifying the minimum and maximum 115 + * limits. (5) can be expressed as 116 + * 117 + * ext_clock / (div * mf / p1) * m * mf >= out_clock_min 118 + * ext_clock / (div * mf / p1) * m * mf <= out_clock_max 119 + * 120 + * or 121 + * 122 + * p1 >= out_clock_min * div / (ext_clock * m) (7) 123 + * p1 <= out_clock_max * div / (ext_clock * m) 124 + * 125 + * Similarly, (4) can be expressed as 126 + * 127 + * mf >= ext_clock * p1 / (int_clock_max * div) (8) 128 + * mf <= ext_clock * p1 / (int_clock_min * div) 129 + * 130 + * We can thus iterate over the restricted p1 range defined by the 131 + * combination of (1) and (7), and then compute the restricted mf range 132 + * defined by the combination of (2), (6) and (8). If the resulting mf 133 + * range is not empty, any value in the mf range is acceptable. We thus 134 + * select the mf lwoer bound and the corresponding p1 value. 135 + */ 136 + if (limits->p1_min == 0) { 137 + dev_err(dev, "pll: P1 minimum value must be >0.\n"); 138 + return -EINVAL; 139 + } 140 + 141 + p1_min = max(limits->p1_min, DIV_ROUND_UP(limits->out_clock_min * div, 142 + pll->ext_clock * pll->m)); 143 + p1_max = min(limits->p1_max, limits->out_clock_max * div / 144 + (pll->ext_clock * pll->m)); 145 + 146 + for (p1 = p1_max & ~1; p1 >= p1_min; p1 -= 2) { 147 + unsigned int mf_inc = p1 / gcd(div, p1); 148 + unsigned int mf_high; 149 + unsigned int mf_low; 150 + 151 + mf_low = max(roundup(mf_min, mf_inc), 152 + DIV_ROUND_UP(pll->ext_clock * p1, 153 + limits->int_clock_max * div)); 154 + mf_high = min(mf_max, pll->ext_clock * p1 / 155 + (limits->int_clock_min * div)); 156 + 157 + if (mf_low > mf_high) 158 + continue; 159 + 160 + pll->n = div * mf_low / p1; 161 + pll->m *= mf_low; 162 + pll->p1 = p1; 163 + dev_dbg(dev, "PLL: N %u M %u P1 %u\n", pll->n, pll->m, pll->p1); 164 + return 0; 165 + } 166 + 167 + dev_err(dev, "pll: no valid N and P1 divisors found.\n"); 168 + return -EINVAL; 169 + } 170 + EXPORT_SYMBOL_GPL(aptina_pll_calculate); 171 + 172 + MODULE_DESCRIPTION("Aptina PLL Helpers"); 173 + MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 174 + MODULE_LICENSE("GPL v2");
+56
drivers/media/video/aptina-pll.h
··· 1 + /* 2 + * Aptina Sensor PLL Configuration 3 + * 4 + * Copyright (C) 2012 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 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 8 + * version 2 as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, but 11 + * WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 + * General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 + * 02110-1301 USA 19 + */ 20 + 21 + #ifndef __APTINA_PLL_H 22 + #define __APTINA_PLL_H 23 + 24 + struct aptina_pll { 25 + unsigned int ext_clock; 26 + unsigned int pix_clock; 27 + 28 + unsigned int n; 29 + unsigned int m; 30 + unsigned int p1; 31 + }; 32 + 33 + struct aptina_pll_limits { 34 + unsigned int ext_clock_min; 35 + unsigned int ext_clock_max; 36 + unsigned int int_clock_min; 37 + unsigned int int_clock_max; 38 + unsigned int out_clock_min; 39 + unsigned int out_clock_max; 40 + unsigned int pix_clock_max; 41 + 42 + unsigned int n_min; 43 + unsigned int n_max; 44 + unsigned int m_min; 45 + unsigned int m_max; 46 + unsigned int p1_min; 47 + unsigned int p1_max; 48 + }; 49 + 50 + struct device; 51 + 52 + int aptina_pll_calculate(struct device *dev, 53 + const struct aptina_pll_limits *limits, 54 + struct aptina_pll *pll); 55 + 56 + #endif /* __APTINA_PLL_H */
+1 -18
drivers/media/video/as3645a.c
··· 881 881 .id_table = as3645a_id_table, 882 882 }; 883 883 884 - static int __init as3645a_init(void) 885 - { 886 - int rval; 887 - 888 - rval = i2c_add_driver(&as3645a_i2c_driver); 889 - if (rval) 890 - pr_err("%s: Failed to register the driver\n", AS3645A_NAME); 891 - 892 - return rval; 893 - } 894 - 895 - static void __exit as3645a_exit(void) 896 - { 897 - i2c_del_driver(&as3645a_i2c_driver); 898 - } 899 - 900 - module_init(as3645a_init); 901 - module_exit(as3645a_exit); 884 + module_i2c_driver(as3645a_i2c_driver); 902 885 903 886 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 904 887 MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones");
+10
drivers/media/video/blackfin/Kconfig
··· 1 + config VIDEO_BLACKFIN_CAPTURE 2 + tristate "Blackfin Video Capture Driver" 3 + depends on VIDEO_V4L2 && BLACKFIN && I2C 4 + select VIDEOBUF2_DMA_CONTIG 5 + help 6 + V4L2 bridge driver for Blackfin video capture device. 7 + Choose PPI or EPPI as its interface. 8 + 9 + To compile this driver as a module, choose M here: the 10 + module will be called bfin_video_capture.
+2
drivers/media/video/blackfin/Makefile
··· 1 + bfin_video_capture-objs := bfin_capture.o ppi.o 2 + obj-$(CONFIG_VIDEO_BLACKFIN_CAPTURE) += bfin_video_capture.o
+1059
drivers/media/video/blackfin/bfin_capture.c
··· 1 + /* 2 + * Analog Devices video capture driver 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 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 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #include <linux/completion.h> 21 + #include <linux/delay.h> 22 + #include <linux/errno.h> 23 + #include <linux/fs.h> 24 + #include <linux/i2c.h> 25 + #include <linux/init.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/io.h> 28 + #include <linux/mm.h> 29 + #include <linux/module.h> 30 + #include <linux/platform_device.h> 31 + #include <linux/slab.h> 32 + #include <linux/time.h> 33 + #include <linux/types.h> 34 + 35 + #include <media/v4l2-chip-ident.h> 36 + #include <media/v4l2-common.h> 37 + #include <media/v4l2-ctrls.h> 38 + #include <media/v4l2-device.h> 39 + #include <media/v4l2-ioctl.h> 40 + #include <media/videobuf2-dma-contig.h> 41 + 42 + #include <asm/dma.h> 43 + 44 + #include <media/blackfin/bfin_capture.h> 45 + #include <media/blackfin/ppi.h> 46 + 47 + #define CAPTURE_DRV_NAME "bfin_capture" 48 + #define BCAP_MIN_NUM_BUF 2 49 + 50 + struct bcap_format { 51 + char *desc; 52 + u32 pixelformat; 53 + enum v4l2_mbus_pixelcode mbus_code; 54 + int bpp; /* bits per pixel */ 55 + }; 56 + 57 + struct bcap_buffer { 58 + struct vb2_buffer vb; 59 + struct list_head list; 60 + }; 61 + 62 + struct bcap_device { 63 + /* capture device instance */ 64 + struct v4l2_device v4l2_dev; 65 + /* v4l2 control handler */ 66 + struct v4l2_ctrl_handler ctrl_handler; 67 + /* device node data */ 68 + struct video_device *video_dev; 69 + /* sub device instance */ 70 + struct v4l2_subdev *sd; 71 + /* capture config */ 72 + struct bfin_capture_config *cfg; 73 + /* ppi interface */ 74 + struct ppi_if *ppi; 75 + /* current input */ 76 + unsigned int cur_input; 77 + /* current selected standard */ 78 + v4l2_std_id std; 79 + /* used to store pixel format */ 80 + struct v4l2_pix_format fmt; 81 + /* bits per pixel*/ 82 + int bpp; 83 + /* used to store sensor supported format */ 84 + struct bcap_format *sensor_formats; 85 + /* number of sensor formats array */ 86 + int num_sensor_formats; 87 + /* pointing to current video buffer */ 88 + struct bcap_buffer *cur_frm; 89 + /* pointing to next video buffer */ 90 + struct bcap_buffer *next_frm; 91 + /* buffer queue used in videobuf2 */ 92 + struct vb2_queue buffer_queue; 93 + /* allocator-specific contexts for each plane */ 94 + struct vb2_alloc_ctx *alloc_ctx; 95 + /* queue of filled frames */ 96 + struct list_head dma_queue; 97 + /* used in videobuf2 callback */ 98 + spinlock_t lock; 99 + /* used to access capture device */ 100 + struct mutex mutex; 101 + /* used to wait ppi to complete one transfer */ 102 + struct completion comp; 103 + /* prepare to stop */ 104 + bool stop; 105 + }; 106 + 107 + struct bcap_fh { 108 + struct v4l2_fh fh; 109 + /* indicates whether this file handle is doing IO */ 110 + bool io_allowed; 111 + }; 112 + 113 + static const struct bcap_format bcap_formats[] = { 114 + { 115 + .desc = "YCbCr 4:2:2 Interleaved UYVY", 116 + .pixelformat = V4L2_PIX_FMT_UYVY, 117 + .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, 118 + .bpp = 16, 119 + }, 120 + { 121 + .desc = "YCbCr 4:2:2 Interleaved YUYV", 122 + .pixelformat = V4L2_PIX_FMT_YUYV, 123 + .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, 124 + .bpp = 16, 125 + }, 126 + { 127 + .desc = "RGB 565", 128 + .pixelformat = V4L2_PIX_FMT_RGB565, 129 + .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, 130 + .bpp = 16, 131 + }, 132 + { 133 + .desc = "RGB 444", 134 + .pixelformat = V4L2_PIX_FMT_RGB444, 135 + .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, 136 + .bpp = 16, 137 + }, 138 + 139 + }; 140 + #define BCAP_MAX_FMTS ARRAY_SIZE(bcap_formats) 141 + 142 + static irqreturn_t bcap_isr(int irq, void *dev_id); 143 + 144 + static struct bcap_buffer *to_bcap_vb(struct vb2_buffer *vb) 145 + { 146 + return container_of(vb, struct bcap_buffer, vb); 147 + } 148 + 149 + static int bcap_init_sensor_formats(struct bcap_device *bcap_dev) 150 + { 151 + enum v4l2_mbus_pixelcode code; 152 + struct bcap_format *sf; 153 + unsigned int num_formats = 0; 154 + int i, j; 155 + 156 + while (!v4l2_subdev_call(bcap_dev->sd, video, 157 + enum_mbus_fmt, num_formats, &code)) 158 + num_formats++; 159 + if (!num_formats) 160 + return -ENXIO; 161 + 162 + sf = kzalloc(num_formats * sizeof(*sf), GFP_KERNEL); 163 + if (!sf) 164 + return -ENOMEM; 165 + 166 + for (i = 0; i < num_formats; i++) { 167 + v4l2_subdev_call(bcap_dev->sd, video, 168 + enum_mbus_fmt, i, &code); 169 + for (j = 0; j < BCAP_MAX_FMTS; j++) 170 + if (code == bcap_formats[j].mbus_code) 171 + break; 172 + if (j == BCAP_MAX_FMTS) { 173 + /* we don't allow this sensor working with our bridge */ 174 + kfree(sf); 175 + return -EINVAL; 176 + } 177 + sf[i] = bcap_formats[j]; 178 + } 179 + bcap_dev->sensor_formats = sf; 180 + bcap_dev->num_sensor_formats = num_formats; 181 + return 0; 182 + } 183 + 184 + static void bcap_free_sensor_formats(struct bcap_device *bcap_dev) 185 + { 186 + bcap_dev->num_sensor_formats = 0; 187 + kfree(bcap_dev->sensor_formats); 188 + bcap_dev->sensor_formats = NULL; 189 + } 190 + 191 + static int bcap_open(struct file *file) 192 + { 193 + struct bcap_device *bcap_dev = video_drvdata(file); 194 + struct video_device *vfd = bcap_dev->video_dev; 195 + struct bcap_fh *bcap_fh; 196 + 197 + if (!bcap_dev->sd) { 198 + v4l2_err(&bcap_dev->v4l2_dev, "No sub device registered\n"); 199 + return -ENODEV; 200 + } 201 + 202 + bcap_fh = kzalloc(sizeof(*bcap_fh), GFP_KERNEL); 203 + if (!bcap_fh) { 204 + v4l2_err(&bcap_dev->v4l2_dev, 205 + "unable to allocate memory for file handle object\n"); 206 + return -ENOMEM; 207 + } 208 + 209 + v4l2_fh_init(&bcap_fh->fh, vfd); 210 + 211 + /* store pointer to v4l2_fh in private_data member of file */ 212 + file->private_data = &bcap_fh->fh; 213 + v4l2_fh_add(&bcap_fh->fh); 214 + bcap_fh->io_allowed = false; 215 + return 0; 216 + } 217 + 218 + static int bcap_release(struct file *file) 219 + { 220 + struct bcap_device *bcap_dev = video_drvdata(file); 221 + struct v4l2_fh *fh = file->private_data; 222 + struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); 223 + 224 + /* if this instance is doing IO */ 225 + if (bcap_fh->io_allowed) 226 + vb2_queue_release(&bcap_dev->buffer_queue); 227 + 228 + file->private_data = NULL; 229 + v4l2_fh_del(&bcap_fh->fh); 230 + v4l2_fh_exit(&bcap_fh->fh); 231 + kfree(bcap_fh); 232 + return 0; 233 + } 234 + 235 + static int bcap_mmap(struct file *file, struct vm_area_struct *vma) 236 + { 237 + struct bcap_device *bcap_dev = video_drvdata(file); 238 + 239 + return vb2_mmap(&bcap_dev->buffer_queue, vma); 240 + } 241 + 242 + #ifndef CONFIG_MMU 243 + static unsigned long bcap_get_unmapped_area(struct file *file, 244 + unsigned long addr, 245 + unsigned long len, 246 + unsigned long pgoff, 247 + unsigned long flags) 248 + { 249 + struct bcap_device *bcap_dev = video_drvdata(file); 250 + 251 + return vb2_get_unmapped_area(&bcap_dev->buffer_queue, 252 + addr, 253 + len, 254 + pgoff, 255 + flags); 256 + } 257 + #endif 258 + 259 + static unsigned int bcap_poll(struct file *file, poll_table *wait) 260 + { 261 + struct bcap_device *bcap_dev = video_drvdata(file); 262 + 263 + return vb2_poll(&bcap_dev->buffer_queue, file, wait); 264 + } 265 + 266 + static int bcap_queue_setup(struct vb2_queue *vq, 267 + const struct v4l2_format *fmt, 268 + unsigned int *nbuffers, unsigned int *nplanes, 269 + unsigned int sizes[], void *alloc_ctxs[]) 270 + { 271 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 272 + 273 + if (*nbuffers < BCAP_MIN_NUM_BUF) 274 + *nbuffers = BCAP_MIN_NUM_BUF; 275 + 276 + *nplanes = 1; 277 + sizes[0] = bcap_dev->fmt.sizeimage; 278 + alloc_ctxs[0] = bcap_dev->alloc_ctx; 279 + 280 + return 0; 281 + } 282 + 283 + static int bcap_buffer_init(struct vb2_buffer *vb) 284 + { 285 + struct bcap_buffer *buf = to_bcap_vb(vb); 286 + 287 + INIT_LIST_HEAD(&buf->list); 288 + return 0; 289 + } 290 + 291 + static int bcap_buffer_prepare(struct vb2_buffer *vb) 292 + { 293 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); 294 + struct bcap_buffer *buf = to_bcap_vb(vb); 295 + unsigned long size; 296 + 297 + size = bcap_dev->fmt.sizeimage; 298 + if (vb2_plane_size(vb, 0) < size) { 299 + v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n", 300 + vb2_plane_size(vb, 0), size); 301 + return -EINVAL; 302 + } 303 + vb2_set_plane_payload(&buf->vb, 0, size); 304 + 305 + return 0; 306 + } 307 + 308 + static void bcap_buffer_queue(struct vb2_buffer *vb) 309 + { 310 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); 311 + struct bcap_buffer *buf = to_bcap_vb(vb); 312 + unsigned long flags; 313 + 314 + spin_lock_irqsave(&bcap_dev->lock, flags); 315 + list_add_tail(&buf->list, &bcap_dev->dma_queue); 316 + spin_unlock_irqrestore(&bcap_dev->lock, flags); 317 + } 318 + 319 + static void bcap_buffer_cleanup(struct vb2_buffer *vb) 320 + { 321 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); 322 + struct bcap_buffer *buf = to_bcap_vb(vb); 323 + unsigned long flags; 324 + 325 + spin_lock_irqsave(&bcap_dev->lock, flags); 326 + list_del_init(&buf->list); 327 + spin_unlock_irqrestore(&bcap_dev->lock, flags); 328 + } 329 + 330 + static void bcap_lock(struct vb2_queue *vq) 331 + { 332 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 333 + mutex_lock(&bcap_dev->mutex); 334 + } 335 + 336 + static void bcap_unlock(struct vb2_queue *vq) 337 + { 338 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 339 + mutex_unlock(&bcap_dev->mutex); 340 + } 341 + 342 + static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) 343 + { 344 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 345 + struct ppi_if *ppi = bcap_dev->ppi; 346 + struct ppi_params params; 347 + int ret; 348 + 349 + /* enable streamon on the sub device */ 350 + ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1); 351 + if (ret && (ret != -ENOIOCTLCMD)) { 352 + v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n"); 353 + return ret; 354 + } 355 + 356 + /* set ppi params */ 357 + params.width = bcap_dev->fmt.width; 358 + params.height = bcap_dev->fmt.height; 359 + params.bpp = bcap_dev->bpp; 360 + params.ppi_control = bcap_dev->cfg->ppi_control; 361 + params.int_mask = bcap_dev->cfg->int_mask; 362 + params.blank_clocks = bcap_dev->cfg->blank_clocks; 363 + ret = ppi->ops->set_params(ppi, &params); 364 + if (ret < 0) { 365 + v4l2_err(&bcap_dev->v4l2_dev, 366 + "Error in setting ppi params\n"); 367 + return ret; 368 + } 369 + 370 + /* attach ppi DMA irq handler */ 371 + ret = ppi->ops->attach_irq(ppi, bcap_isr); 372 + if (ret < 0) { 373 + v4l2_err(&bcap_dev->v4l2_dev, 374 + "Error in attaching interrupt handler\n"); 375 + return ret; 376 + } 377 + 378 + INIT_COMPLETION(bcap_dev->comp); 379 + bcap_dev->stop = false; 380 + return 0; 381 + } 382 + 383 + static int bcap_stop_streaming(struct vb2_queue *vq) 384 + { 385 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 386 + struct ppi_if *ppi = bcap_dev->ppi; 387 + int ret; 388 + 389 + if (!vb2_is_streaming(vq)) 390 + return 0; 391 + 392 + bcap_dev->stop = true; 393 + wait_for_completion(&bcap_dev->comp); 394 + ppi->ops->stop(ppi); 395 + ppi->ops->detach_irq(ppi); 396 + ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 0); 397 + if (ret && (ret != -ENOIOCTLCMD)) 398 + v4l2_err(&bcap_dev->v4l2_dev, 399 + "stream off failed in subdev\n"); 400 + 401 + /* release all active buffers */ 402 + while (!list_empty(&bcap_dev->dma_queue)) { 403 + bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, 404 + struct bcap_buffer, list); 405 + list_del(&bcap_dev->next_frm->list); 406 + vb2_buffer_done(&bcap_dev->next_frm->vb, VB2_BUF_STATE_ERROR); 407 + } 408 + return 0; 409 + } 410 + 411 + static struct vb2_ops bcap_video_qops = { 412 + .queue_setup = bcap_queue_setup, 413 + .buf_init = bcap_buffer_init, 414 + .buf_prepare = bcap_buffer_prepare, 415 + .buf_cleanup = bcap_buffer_cleanup, 416 + .buf_queue = bcap_buffer_queue, 417 + .wait_prepare = bcap_unlock, 418 + .wait_finish = bcap_lock, 419 + .start_streaming = bcap_start_streaming, 420 + .stop_streaming = bcap_stop_streaming, 421 + }; 422 + 423 + static int bcap_reqbufs(struct file *file, void *priv, 424 + struct v4l2_requestbuffers *req_buf) 425 + { 426 + struct bcap_device *bcap_dev = video_drvdata(file); 427 + struct vb2_queue *vq = &bcap_dev->buffer_queue; 428 + struct v4l2_fh *fh = file->private_data; 429 + struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); 430 + 431 + if (vb2_is_busy(vq)) 432 + return -EBUSY; 433 + 434 + bcap_fh->io_allowed = true; 435 + 436 + return vb2_reqbufs(vq, req_buf); 437 + } 438 + 439 + static int bcap_querybuf(struct file *file, void *priv, 440 + struct v4l2_buffer *buf) 441 + { 442 + struct bcap_device *bcap_dev = video_drvdata(file); 443 + 444 + return vb2_querybuf(&bcap_dev->buffer_queue, buf); 445 + } 446 + 447 + static int bcap_qbuf(struct file *file, void *priv, 448 + struct v4l2_buffer *buf) 449 + { 450 + struct bcap_device *bcap_dev = video_drvdata(file); 451 + struct v4l2_fh *fh = file->private_data; 452 + struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); 453 + 454 + if (!bcap_fh->io_allowed) 455 + return -EBUSY; 456 + 457 + return vb2_qbuf(&bcap_dev->buffer_queue, buf); 458 + } 459 + 460 + static int bcap_dqbuf(struct file *file, void *priv, 461 + struct v4l2_buffer *buf) 462 + { 463 + struct bcap_device *bcap_dev = video_drvdata(file); 464 + struct v4l2_fh *fh = file->private_data; 465 + struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); 466 + 467 + if (!bcap_fh->io_allowed) 468 + return -EBUSY; 469 + 470 + return vb2_dqbuf(&bcap_dev->buffer_queue, 471 + buf, file->f_flags & O_NONBLOCK); 472 + } 473 + 474 + static irqreturn_t bcap_isr(int irq, void *dev_id) 475 + { 476 + struct ppi_if *ppi = dev_id; 477 + struct bcap_device *bcap_dev = ppi->priv; 478 + struct timeval timevalue; 479 + struct vb2_buffer *vb = &bcap_dev->cur_frm->vb; 480 + dma_addr_t addr; 481 + 482 + spin_lock(&bcap_dev->lock); 483 + 484 + if (bcap_dev->cur_frm != bcap_dev->next_frm) { 485 + do_gettimeofday(&timevalue); 486 + vb->v4l2_buf.timestamp = timevalue; 487 + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 488 + bcap_dev->cur_frm = bcap_dev->next_frm; 489 + } 490 + 491 + ppi->ops->stop(ppi); 492 + 493 + if (bcap_dev->stop) { 494 + complete(&bcap_dev->comp); 495 + } else { 496 + if (!list_empty(&bcap_dev->dma_queue)) { 497 + bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, 498 + struct bcap_buffer, list); 499 + list_del(&bcap_dev->next_frm->list); 500 + addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->next_frm->vb, 0); 501 + ppi->ops->update_addr(ppi, (unsigned long)addr); 502 + } 503 + ppi->ops->start(ppi); 504 + } 505 + 506 + spin_unlock(&bcap_dev->lock); 507 + 508 + return IRQ_HANDLED; 509 + } 510 + 511 + static int bcap_streamon(struct file *file, void *priv, 512 + enum v4l2_buf_type buf_type) 513 + { 514 + struct bcap_device *bcap_dev = video_drvdata(file); 515 + struct bcap_fh *fh = file->private_data; 516 + struct ppi_if *ppi = bcap_dev->ppi; 517 + dma_addr_t addr; 518 + int ret; 519 + 520 + if (!fh->io_allowed) 521 + return -EBUSY; 522 + 523 + /* call streamon to start streaming in videobuf */ 524 + ret = vb2_streamon(&bcap_dev->buffer_queue, buf_type); 525 + if (ret) 526 + return ret; 527 + 528 + /* if dma queue is empty, return error */ 529 + if (list_empty(&bcap_dev->dma_queue)) { 530 + v4l2_err(&bcap_dev->v4l2_dev, "dma queue is empty\n"); 531 + ret = -EINVAL; 532 + goto err; 533 + } 534 + 535 + /* get the next frame from the dma queue */ 536 + bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, 537 + struct bcap_buffer, list); 538 + bcap_dev->cur_frm = bcap_dev->next_frm; 539 + /* remove buffer from the dma queue */ 540 + list_del(&bcap_dev->cur_frm->list); 541 + addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); 542 + /* update DMA address */ 543 + ppi->ops->update_addr(ppi, (unsigned long)addr); 544 + /* enable ppi */ 545 + ppi->ops->start(ppi); 546 + 547 + return 0; 548 + err: 549 + vb2_streamoff(&bcap_dev->buffer_queue, buf_type); 550 + return ret; 551 + } 552 + 553 + static int bcap_streamoff(struct file *file, void *priv, 554 + enum v4l2_buf_type buf_type) 555 + { 556 + struct bcap_device *bcap_dev = video_drvdata(file); 557 + struct bcap_fh *fh = file->private_data; 558 + 559 + if (!fh->io_allowed) 560 + return -EBUSY; 561 + 562 + return vb2_streamoff(&bcap_dev->buffer_queue, buf_type); 563 + } 564 + 565 + static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std) 566 + { 567 + struct bcap_device *bcap_dev = video_drvdata(file); 568 + 569 + return v4l2_subdev_call(bcap_dev->sd, video, querystd, std); 570 + } 571 + 572 + static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std) 573 + { 574 + struct bcap_device *bcap_dev = video_drvdata(file); 575 + 576 + *std = bcap_dev->std; 577 + return 0; 578 + } 579 + 580 + static int bcap_s_std(struct file *file, void *priv, v4l2_std_id *std) 581 + { 582 + struct bcap_device *bcap_dev = video_drvdata(file); 583 + int ret; 584 + 585 + if (vb2_is_busy(&bcap_dev->buffer_queue)) 586 + return -EBUSY; 587 + 588 + ret = v4l2_subdev_call(bcap_dev->sd, core, s_std, *std); 589 + if (ret < 0) 590 + return ret; 591 + 592 + bcap_dev->std = *std; 593 + return 0; 594 + } 595 + 596 + static int bcap_enum_input(struct file *file, void *priv, 597 + struct v4l2_input *input) 598 + { 599 + struct bcap_device *bcap_dev = video_drvdata(file); 600 + struct bfin_capture_config *config = bcap_dev->cfg; 601 + int ret; 602 + u32 status; 603 + 604 + if (input->index >= config->num_inputs) 605 + return -EINVAL; 606 + 607 + *input = config->inputs[input->index]; 608 + /* get input status */ 609 + ret = v4l2_subdev_call(bcap_dev->sd, video, g_input_status, &status); 610 + if (!ret) 611 + input->status = status; 612 + return 0; 613 + } 614 + 615 + static int bcap_g_input(struct file *file, void *priv, unsigned int *index) 616 + { 617 + struct bcap_device *bcap_dev = video_drvdata(file); 618 + 619 + *index = bcap_dev->cur_input; 620 + return 0; 621 + } 622 + 623 + static int bcap_s_input(struct file *file, void *priv, unsigned int index) 624 + { 625 + struct bcap_device *bcap_dev = video_drvdata(file); 626 + struct bfin_capture_config *config = bcap_dev->cfg; 627 + struct bcap_route *route; 628 + int ret; 629 + 630 + if (vb2_is_busy(&bcap_dev->buffer_queue)) 631 + return -EBUSY; 632 + 633 + if (index >= config->num_inputs) 634 + return -EINVAL; 635 + 636 + route = &config->routes[index]; 637 + ret = v4l2_subdev_call(bcap_dev->sd, video, s_routing, 638 + route->input, route->output, 0); 639 + if ((ret < 0) && (ret != -ENOIOCTLCMD)) { 640 + v4l2_err(&bcap_dev->v4l2_dev, "Failed to set input\n"); 641 + return ret; 642 + } 643 + bcap_dev->cur_input = index; 644 + return 0; 645 + } 646 + 647 + static int bcap_try_format(struct bcap_device *bcap, 648 + struct v4l2_pix_format *pixfmt, 649 + enum v4l2_mbus_pixelcode *mbus_code, 650 + int *bpp) 651 + { 652 + struct bcap_format *sf = bcap->sensor_formats; 653 + struct bcap_format *fmt = NULL; 654 + struct v4l2_mbus_framefmt mbus_fmt; 655 + int ret, i; 656 + 657 + for (i = 0; i < bcap->num_sensor_formats; i++) { 658 + fmt = &sf[i]; 659 + if (pixfmt->pixelformat == fmt->pixelformat) 660 + break; 661 + } 662 + if (i == bcap->num_sensor_formats) 663 + fmt = &sf[0]; 664 + 665 + if (mbus_code) 666 + *mbus_code = fmt->mbus_code; 667 + if (bpp) 668 + *bpp = fmt->bpp; 669 + v4l2_fill_mbus_format(&mbus_fmt, pixfmt, fmt->mbus_code); 670 + ret = v4l2_subdev_call(bcap->sd, video, 671 + try_mbus_fmt, &mbus_fmt); 672 + if (ret < 0) 673 + return ret; 674 + v4l2_fill_pix_format(pixfmt, &mbus_fmt); 675 + pixfmt->bytesperline = pixfmt->width * fmt->bpp / 8; 676 + pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; 677 + return 0; 678 + } 679 + 680 + static int bcap_enum_fmt_vid_cap(struct file *file, void *priv, 681 + struct v4l2_fmtdesc *fmt) 682 + { 683 + struct bcap_device *bcap_dev = video_drvdata(file); 684 + struct bcap_format *sf = bcap_dev->sensor_formats; 685 + 686 + if (fmt->index >= bcap_dev->num_sensor_formats) 687 + return -EINVAL; 688 + 689 + fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 690 + strlcpy(fmt->description, 691 + sf[fmt->index].desc, 692 + sizeof(fmt->description)); 693 + fmt->pixelformat = sf[fmt->index].pixelformat; 694 + return 0; 695 + } 696 + 697 + static int bcap_try_fmt_vid_cap(struct file *file, void *priv, 698 + struct v4l2_format *fmt) 699 + { 700 + struct bcap_device *bcap_dev = video_drvdata(file); 701 + struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 702 + 703 + return bcap_try_format(bcap_dev, pixfmt, NULL, NULL); 704 + } 705 + 706 + static int bcap_g_fmt_vid_cap(struct file *file, void *priv, 707 + struct v4l2_format *fmt) 708 + { 709 + struct bcap_device *bcap_dev = video_drvdata(file); 710 + 711 + fmt->fmt.pix = bcap_dev->fmt; 712 + return 0; 713 + } 714 + 715 + static int bcap_s_fmt_vid_cap(struct file *file, void *priv, 716 + struct v4l2_format *fmt) 717 + { 718 + struct bcap_device *bcap_dev = video_drvdata(file); 719 + struct v4l2_mbus_framefmt mbus_fmt; 720 + enum v4l2_mbus_pixelcode mbus_code; 721 + struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 722 + int ret, bpp; 723 + 724 + if (vb2_is_busy(&bcap_dev->buffer_queue)) 725 + return -EBUSY; 726 + 727 + /* see if format works */ 728 + ret = bcap_try_format(bcap_dev, pixfmt, &mbus_code, &bpp); 729 + if (ret < 0) 730 + return ret; 731 + 732 + v4l2_fill_mbus_format(&mbus_fmt, pixfmt, mbus_code); 733 + ret = v4l2_subdev_call(bcap_dev->sd, video, s_mbus_fmt, &mbus_fmt); 734 + if (ret < 0) 735 + return ret; 736 + bcap_dev->fmt = *pixfmt; 737 + bcap_dev->bpp = bpp; 738 + return 0; 739 + } 740 + 741 + static int bcap_querycap(struct file *file, void *priv, 742 + struct v4l2_capability *cap) 743 + { 744 + struct bcap_device *bcap_dev = video_drvdata(file); 745 + 746 + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 747 + strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver)); 748 + strlcpy(cap->bus_info, "Blackfin Platform", sizeof(cap->bus_info)); 749 + strlcpy(cap->card, bcap_dev->cfg->card_name, sizeof(cap->card)); 750 + return 0; 751 + } 752 + 753 + static int bcap_g_parm(struct file *file, void *fh, 754 + struct v4l2_streamparm *a) 755 + { 756 + struct bcap_device *bcap_dev = video_drvdata(file); 757 + 758 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 759 + return -EINVAL; 760 + return v4l2_subdev_call(bcap_dev->sd, video, g_parm, a); 761 + } 762 + 763 + static int bcap_s_parm(struct file *file, void *fh, 764 + struct v4l2_streamparm *a) 765 + { 766 + struct bcap_device *bcap_dev = video_drvdata(file); 767 + 768 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 769 + return -EINVAL; 770 + return v4l2_subdev_call(bcap_dev->sd, video, s_parm, a); 771 + } 772 + 773 + static int bcap_g_chip_ident(struct file *file, void *priv, 774 + struct v4l2_dbg_chip_ident *chip) 775 + { 776 + struct bcap_device *bcap_dev = video_drvdata(file); 777 + 778 + chip->ident = V4L2_IDENT_NONE; 779 + chip->revision = 0; 780 + if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && 781 + chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 782 + return -EINVAL; 783 + 784 + return v4l2_subdev_call(bcap_dev->sd, core, 785 + g_chip_ident, chip); 786 + } 787 + 788 + #ifdef CONFIG_VIDEO_ADV_DEBUG 789 + static int bcap_dbg_g_register(struct file *file, void *priv, 790 + struct v4l2_dbg_register *reg) 791 + { 792 + struct bcap_device *bcap_dev = video_drvdata(file); 793 + 794 + return v4l2_subdev_call(bcap_dev->sd, core, 795 + g_register, reg); 796 + } 797 + 798 + static int bcap_dbg_s_register(struct file *file, void *priv, 799 + struct v4l2_dbg_register *reg) 800 + { 801 + struct bcap_device *bcap_dev = video_drvdata(file); 802 + 803 + return v4l2_subdev_call(bcap_dev->sd, core, 804 + s_register, reg); 805 + } 806 + #endif 807 + 808 + static int bcap_log_status(struct file *file, void *priv) 809 + { 810 + struct bcap_device *bcap_dev = video_drvdata(file); 811 + /* status for sub devices */ 812 + v4l2_device_call_all(&bcap_dev->v4l2_dev, 0, core, log_status); 813 + return 0; 814 + } 815 + 816 + static const struct v4l2_ioctl_ops bcap_ioctl_ops = { 817 + .vidioc_querycap = bcap_querycap, 818 + .vidioc_g_fmt_vid_cap = bcap_g_fmt_vid_cap, 819 + .vidioc_enum_fmt_vid_cap = bcap_enum_fmt_vid_cap, 820 + .vidioc_s_fmt_vid_cap = bcap_s_fmt_vid_cap, 821 + .vidioc_try_fmt_vid_cap = bcap_try_fmt_vid_cap, 822 + .vidioc_enum_input = bcap_enum_input, 823 + .vidioc_g_input = bcap_g_input, 824 + .vidioc_s_input = bcap_s_input, 825 + .vidioc_querystd = bcap_querystd, 826 + .vidioc_s_std = bcap_s_std, 827 + .vidioc_g_std = bcap_g_std, 828 + .vidioc_reqbufs = bcap_reqbufs, 829 + .vidioc_querybuf = bcap_querybuf, 830 + .vidioc_qbuf = bcap_qbuf, 831 + .vidioc_dqbuf = bcap_dqbuf, 832 + .vidioc_streamon = bcap_streamon, 833 + .vidioc_streamoff = bcap_streamoff, 834 + .vidioc_g_parm = bcap_g_parm, 835 + .vidioc_s_parm = bcap_s_parm, 836 + .vidioc_g_chip_ident = bcap_g_chip_ident, 837 + #ifdef CONFIG_VIDEO_ADV_DEBUG 838 + .vidioc_g_register = bcap_dbg_g_register, 839 + .vidioc_s_register = bcap_dbg_s_register, 840 + #endif 841 + .vidioc_log_status = bcap_log_status, 842 + }; 843 + 844 + static struct v4l2_file_operations bcap_fops = { 845 + .owner = THIS_MODULE, 846 + .open = bcap_open, 847 + .release = bcap_release, 848 + .unlocked_ioctl = video_ioctl2, 849 + .mmap = bcap_mmap, 850 + #ifndef CONFIG_MMU 851 + .get_unmapped_area = bcap_get_unmapped_area, 852 + #endif 853 + .poll = bcap_poll 854 + }; 855 + 856 + static int __devinit bcap_probe(struct platform_device *pdev) 857 + { 858 + struct bcap_device *bcap_dev; 859 + struct video_device *vfd; 860 + struct i2c_adapter *i2c_adap; 861 + struct bfin_capture_config *config; 862 + struct vb2_queue *q; 863 + int ret; 864 + 865 + config = pdev->dev.platform_data; 866 + if (!config) { 867 + v4l2_err(pdev->dev.driver, "Unable to get board config\n"); 868 + return -ENODEV; 869 + } 870 + 871 + bcap_dev = kzalloc(sizeof(*bcap_dev), GFP_KERNEL); 872 + if (!bcap_dev) { 873 + v4l2_err(pdev->dev.driver, "Unable to alloc bcap_dev\n"); 874 + return -ENOMEM; 875 + } 876 + 877 + bcap_dev->cfg = config; 878 + 879 + bcap_dev->ppi = ppi_create_instance(config->ppi_info); 880 + if (!bcap_dev->ppi) { 881 + v4l2_err(pdev->dev.driver, "Unable to create ppi\n"); 882 + ret = -ENODEV; 883 + goto err_free_dev; 884 + } 885 + bcap_dev->ppi->priv = bcap_dev; 886 + 887 + bcap_dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 888 + if (IS_ERR(bcap_dev->alloc_ctx)) { 889 + ret = PTR_ERR(bcap_dev->alloc_ctx); 890 + goto err_free_ppi; 891 + } 892 + 893 + vfd = video_device_alloc(); 894 + if (!vfd) { 895 + ret = -ENOMEM; 896 + v4l2_err(pdev->dev.driver, "Unable to alloc video device\n"); 897 + goto err_cleanup_ctx; 898 + } 899 + 900 + /* initialize field of video device */ 901 + vfd->release = video_device_release; 902 + vfd->fops = &bcap_fops; 903 + vfd->ioctl_ops = &bcap_ioctl_ops; 904 + vfd->tvnorms = 0; 905 + vfd->v4l2_dev = &bcap_dev->v4l2_dev; 906 + set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); 907 + strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name)); 908 + bcap_dev->video_dev = vfd; 909 + 910 + ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev); 911 + if (ret) { 912 + v4l2_err(pdev->dev.driver, 913 + "Unable to register v4l2 device\n"); 914 + goto err_release_vdev; 915 + } 916 + v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n"); 917 + 918 + bcap_dev->v4l2_dev.ctrl_handler = &bcap_dev->ctrl_handler; 919 + ret = v4l2_ctrl_handler_init(&bcap_dev->ctrl_handler, 0); 920 + if (ret) { 921 + v4l2_err(&bcap_dev->v4l2_dev, 922 + "Unable to init control handler\n"); 923 + goto err_unreg_v4l2; 924 + } 925 + 926 + spin_lock_init(&bcap_dev->lock); 927 + /* initialize queue */ 928 + q = &bcap_dev->buffer_queue; 929 + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 930 + q->io_modes = VB2_MMAP; 931 + q->drv_priv = bcap_dev; 932 + q->buf_struct_size = sizeof(struct bcap_buffer); 933 + q->ops = &bcap_video_qops; 934 + q->mem_ops = &vb2_dma_contig_memops; 935 + 936 + vb2_queue_init(q); 937 + 938 + mutex_init(&bcap_dev->mutex); 939 + init_completion(&bcap_dev->comp); 940 + 941 + /* init video dma queues */ 942 + INIT_LIST_HEAD(&bcap_dev->dma_queue); 943 + 944 + vfd->lock = &bcap_dev->mutex; 945 + 946 + /* register video device */ 947 + ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1); 948 + if (ret) { 949 + v4l2_err(&bcap_dev->v4l2_dev, 950 + "Unable to register video device\n"); 951 + goto err_free_handler; 952 + } 953 + video_set_drvdata(bcap_dev->video_dev, bcap_dev); 954 + v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n", 955 + video_device_node_name(vfd)); 956 + 957 + /* load up the subdevice */ 958 + i2c_adap = i2c_get_adapter(config->i2c_adapter_id); 959 + if (!i2c_adap) { 960 + v4l2_err(&bcap_dev->v4l2_dev, 961 + "Unable to find i2c adapter\n"); 962 + goto err_unreg_vdev; 963 + 964 + } 965 + bcap_dev->sd = v4l2_i2c_new_subdev_board(&bcap_dev->v4l2_dev, 966 + i2c_adap, 967 + &config->board_info, 968 + NULL); 969 + if (bcap_dev->sd) { 970 + int i; 971 + /* update tvnorms from the sub devices */ 972 + for (i = 0; i < config->num_inputs; i++) 973 + vfd->tvnorms |= config->inputs[i].std; 974 + } else { 975 + v4l2_err(&bcap_dev->v4l2_dev, 976 + "Unable to register sub device\n"); 977 + goto err_unreg_vdev; 978 + } 979 + 980 + v4l2_info(&bcap_dev->v4l2_dev, "v4l2 sub device registered\n"); 981 + 982 + /* now we can probe the default state */ 983 + if (vfd->tvnorms) { 984 + v4l2_std_id std; 985 + ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std); 986 + if (ret) { 987 + v4l2_err(&bcap_dev->v4l2_dev, 988 + "Unable to get std\n"); 989 + goto err_unreg_vdev; 990 + } 991 + bcap_dev->std = std; 992 + } 993 + ret = bcap_init_sensor_formats(bcap_dev); 994 + if (ret) { 995 + v4l2_err(&bcap_dev->v4l2_dev, 996 + "Unable to create sensor formats table\n"); 997 + goto err_unreg_vdev; 998 + } 999 + return 0; 1000 + err_unreg_vdev: 1001 + video_unregister_device(bcap_dev->video_dev); 1002 + bcap_dev->video_dev = NULL; 1003 + err_free_handler: 1004 + v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); 1005 + err_unreg_v4l2: 1006 + v4l2_device_unregister(&bcap_dev->v4l2_dev); 1007 + err_release_vdev: 1008 + if (bcap_dev->video_dev) 1009 + video_device_release(bcap_dev->video_dev); 1010 + err_cleanup_ctx: 1011 + vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); 1012 + err_free_ppi: 1013 + ppi_delete_instance(bcap_dev->ppi); 1014 + err_free_dev: 1015 + kfree(bcap_dev); 1016 + return ret; 1017 + } 1018 + 1019 + static int __devexit bcap_remove(struct platform_device *pdev) 1020 + { 1021 + struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); 1022 + struct bcap_device *bcap_dev = container_of(v4l2_dev, 1023 + struct bcap_device, v4l2_dev); 1024 + 1025 + bcap_free_sensor_formats(bcap_dev); 1026 + video_unregister_device(bcap_dev->video_dev); 1027 + v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); 1028 + v4l2_device_unregister(v4l2_dev); 1029 + vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); 1030 + ppi_delete_instance(bcap_dev->ppi); 1031 + kfree(bcap_dev); 1032 + return 0; 1033 + } 1034 + 1035 + static struct platform_driver bcap_driver = { 1036 + .driver = { 1037 + .name = CAPTURE_DRV_NAME, 1038 + .owner = THIS_MODULE, 1039 + }, 1040 + .probe = bcap_probe, 1041 + .remove = __devexit_p(bcap_remove), 1042 + }; 1043 + 1044 + static __init int bcap_init(void) 1045 + { 1046 + return platform_driver_register(&bcap_driver); 1047 + } 1048 + 1049 + static __exit void bcap_exit(void) 1050 + { 1051 + platform_driver_unregister(&bcap_driver); 1052 + } 1053 + 1054 + module_init(bcap_init); 1055 + module_exit(bcap_exit); 1056 + 1057 + MODULE_DESCRIPTION("Analog Devices blackfin video capture driver"); 1058 + MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>"); 1059 + MODULE_LICENSE("GPL v2");
+271
drivers/media/video/blackfin/ppi.c
··· 1 + /* 2 + * ppi.c Analog Devices Parallel Peripheral Interface driver 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 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 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #include <linux/slab.h> 21 + 22 + #include <asm/bfin_ppi.h> 23 + #include <asm/blackfin.h> 24 + #include <asm/cacheflush.h> 25 + #include <asm/dma.h> 26 + #include <asm/portmux.h> 27 + 28 + #include <media/blackfin/ppi.h> 29 + 30 + static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler); 31 + static void ppi_detach_irq(struct ppi_if *ppi); 32 + static int ppi_start(struct ppi_if *ppi); 33 + static int ppi_stop(struct ppi_if *ppi); 34 + static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params); 35 + static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr); 36 + 37 + static const struct ppi_ops ppi_ops = { 38 + .attach_irq = ppi_attach_irq, 39 + .detach_irq = ppi_detach_irq, 40 + .start = ppi_start, 41 + .stop = ppi_stop, 42 + .set_params = ppi_set_params, 43 + .update_addr = ppi_update_addr, 44 + }; 45 + 46 + static irqreturn_t ppi_irq_err(int irq, void *dev_id) 47 + { 48 + struct ppi_if *ppi = dev_id; 49 + const struct ppi_info *info = ppi->info; 50 + 51 + switch (info->type) { 52 + case PPI_TYPE_PPI: 53 + { 54 + struct bfin_ppi_regs *reg = info->base; 55 + unsigned short status; 56 + 57 + /* register on bf561 is cleared when read 58 + * others are W1C 59 + */ 60 + status = bfin_read16(&reg->status); 61 + bfin_write16(&reg->status, 0xff00); 62 + break; 63 + } 64 + case PPI_TYPE_EPPI: 65 + { 66 + struct bfin_eppi_regs *reg = info->base; 67 + bfin_write16(&reg->status, 0xffff); 68 + break; 69 + } 70 + default: 71 + break; 72 + } 73 + 74 + return IRQ_HANDLED; 75 + } 76 + 77 + static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler) 78 + { 79 + const struct ppi_info *info = ppi->info; 80 + int ret; 81 + 82 + ret = request_dma(info->dma_ch, "PPI_DMA"); 83 + 84 + if (ret) { 85 + pr_err("Unable to allocate DMA channel for PPI\n"); 86 + return ret; 87 + } 88 + set_dma_callback(info->dma_ch, handler, ppi); 89 + 90 + if (ppi->err_int) { 91 + ret = request_irq(info->irq_err, ppi_irq_err, 0, "PPI ERROR", ppi); 92 + if (ret) { 93 + pr_err("Unable to allocate IRQ for PPI\n"); 94 + free_dma(info->dma_ch); 95 + } 96 + } 97 + return ret; 98 + } 99 + 100 + static void ppi_detach_irq(struct ppi_if *ppi) 101 + { 102 + const struct ppi_info *info = ppi->info; 103 + 104 + if (ppi->err_int) 105 + free_irq(info->irq_err, ppi); 106 + free_dma(info->dma_ch); 107 + } 108 + 109 + static int ppi_start(struct ppi_if *ppi) 110 + { 111 + const struct ppi_info *info = ppi->info; 112 + 113 + /* enable DMA */ 114 + enable_dma(info->dma_ch); 115 + 116 + /* enable PPI */ 117 + ppi->ppi_control |= PORT_EN; 118 + switch (info->type) { 119 + case PPI_TYPE_PPI: 120 + { 121 + struct bfin_ppi_regs *reg = info->base; 122 + bfin_write16(&reg->control, ppi->ppi_control); 123 + break; 124 + } 125 + case PPI_TYPE_EPPI: 126 + { 127 + struct bfin_eppi_regs *reg = info->base; 128 + bfin_write32(&reg->control, ppi->ppi_control); 129 + break; 130 + } 131 + default: 132 + return -EINVAL; 133 + } 134 + 135 + SSYNC(); 136 + return 0; 137 + } 138 + 139 + static int ppi_stop(struct ppi_if *ppi) 140 + { 141 + const struct ppi_info *info = ppi->info; 142 + 143 + /* disable PPI */ 144 + ppi->ppi_control &= ~PORT_EN; 145 + switch (info->type) { 146 + case PPI_TYPE_PPI: 147 + { 148 + struct bfin_ppi_regs *reg = info->base; 149 + bfin_write16(&reg->control, ppi->ppi_control); 150 + break; 151 + } 152 + case PPI_TYPE_EPPI: 153 + { 154 + struct bfin_eppi_regs *reg = info->base; 155 + bfin_write32(&reg->control, ppi->ppi_control); 156 + break; 157 + } 158 + default: 159 + return -EINVAL; 160 + } 161 + 162 + /* disable DMA */ 163 + clear_dma_irqstat(info->dma_ch); 164 + disable_dma(info->dma_ch); 165 + 166 + SSYNC(); 167 + return 0; 168 + } 169 + 170 + static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params) 171 + { 172 + const struct ppi_info *info = ppi->info; 173 + int dma32 = 0; 174 + int dma_config, bytes_per_line, lines_per_frame; 175 + 176 + bytes_per_line = params->width * params->bpp / 8; 177 + lines_per_frame = params->height; 178 + if (params->int_mask == 0xFFFFFFFF) 179 + ppi->err_int = false; 180 + else 181 + ppi->err_int = true; 182 + 183 + dma_config = (DMA_FLOW_STOP | WNR | RESTART | DMA2D | DI_EN); 184 + ppi->ppi_control = params->ppi_control & ~PORT_EN; 185 + switch (info->type) { 186 + case PPI_TYPE_PPI: 187 + { 188 + struct bfin_ppi_regs *reg = info->base; 189 + 190 + if (params->ppi_control & DMA32) 191 + dma32 = 1; 192 + 193 + bfin_write16(&reg->control, ppi->ppi_control); 194 + bfin_write16(&reg->count, bytes_per_line - 1); 195 + bfin_write16(&reg->frame, lines_per_frame); 196 + break; 197 + } 198 + case PPI_TYPE_EPPI: 199 + { 200 + struct bfin_eppi_regs *reg = info->base; 201 + 202 + if ((params->ppi_control & PACK_EN) 203 + || (params->ppi_control & 0x38000) > DLEN_16) 204 + dma32 = 1; 205 + 206 + bfin_write32(&reg->control, ppi->ppi_control); 207 + bfin_write16(&reg->line, bytes_per_line + params->blank_clocks); 208 + bfin_write16(&reg->frame, lines_per_frame); 209 + bfin_write16(&reg->hdelay, 0); 210 + bfin_write16(&reg->vdelay, 0); 211 + bfin_write16(&reg->hcount, bytes_per_line); 212 + bfin_write16(&reg->vcount, lines_per_frame); 213 + break; 214 + } 215 + default: 216 + return -EINVAL; 217 + } 218 + 219 + if (dma32) { 220 + dma_config |= WDSIZE_32; 221 + set_dma_x_count(info->dma_ch, bytes_per_line >> 2); 222 + set_dma_x_modify(info->dma_ch, 4); 223 + set_dma_y_modify(info->dma_ch, 4); 224 + } else { 225 + dma_config |= WDSIZE_16; 226 + set_dma_x_count(info->dma_ch, bytes_per_line >> 1); 227 + set_dma_x_modify(info->dma_ch, 2); 228 + set_dma_y_modify(info->dma_ch, 2); 229 + } 230 + set_dma_y_count(info->dma_ch, lines_per_frame); 231 + set_dma_config(info->dma_ch, dma_config); 232 + 233 + SSYNC(); 234 + return 0; 235 + } 236 + 237 + static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr) 238 + { 239 + set_dma_start_addr(ppi->info->dma_ch, addr); 240 + } 241 + 242 + struct ppi_if *ppi_create_instance(const struct ppi_info *info) 243 + { 244 + struct ppi_if *ppi; 245 + 246 + if (!info || !info->pin_req) 247 + return NULL; 248 + 249 + if (peripheral_request_list(info->pin_req, KBUILD_MODNAME)) { 250 + pr_err("request peripheral failed\n"); 251 + return NULL; 252 + } 253 + 254 + ppi = kzalloc(sizeof(*ppi), GFP_KERNEL); 255 + if (!ppi) { 256 + peripheral_free_list(info->pin_req); 257 + pr_err("unable to allocate memory for ppi handle\n"); 258 + return NULL; 259 + } 260 + ppi->ops = &ppi_ops; 261 + ppi->info = info; 262 + 263 + pr_info("ppi probe success\n"); 264 + return ppi; 265 + } 266 + 267 + void ppi_delete_instance(struct ppi_if *ppi) 268 + { 269 + peripheral_free_list(ppi->info->pin_req); 270 + kfree(ppi); 271 + }
+1 -12
drivers/media/video/bt819.c
··· 514 514 .id_table = bt819_id, 515 515 }; 516 516 517 - static __init int init_bt819(void) 518 - { 519 - return i2c_add_driver(&bt819_driver); 520 - } 521 - 522 - static __exit void exit_bt819(void) 523 - { 524 - i2c_del_driver(&bt819_driver); 525 - } 526 - 527 - module_init(init_bt819); 528 - module_exit(exit_bt819); 517 + module_i2c_driver(bt819_driver);
+1 -12
drivers/media/video/bt856.c
··· 270 270 .id_table = bt856_id, 271 271 }; 272 272 273 - static __init int init_bt856(void) 274 - { 275 - return i2c_add_driver(&bt856_driver); 276 - } 277 - 278 - static __exit void exit_bt856(void) 279 - { 280 - i2c_del_driver(&bt856_driver); 281 - } 282 - 283 - module_init(init_bt856); 284 - module_exit(exit_bt856); 273 + module_i2c_driver(bt856_driver);
+1 -12
drivers/media/video/bt866.c
··· 240 240 .id_table = bt866_id, 241 241 }; 242 242 243 - static __init int init_bt866(void) 244 - { 245 - return i2c_add_driver(&bt866_driver); 246 - } 247 - 248 - static __exit void exit_bt866(void) 249 - { 250 - i2c_del_driver(&bt866_driver); 251 - } 252 - 253 - module_init(init_bt866); 254 - module_exit(exit_bt866); 243 + module_i2c_driver(bt866_driver);
-4
drivers/media/video/bt8xx/bttv-driver.c
··· 2035 2035 struct bttv_fh *fh = f; 2036 2036 struct bttv *btv = fh->btv; 2037 2037 2038 - pr_info("%d: ======== START STATUS CARD #%d ========\n", 2039 - btv->c.nr, btv->c.nr); 2040 2038 bttv_call_all(btv, core, log_status); 2041 - pr_info("%d: ======== END STATUS CARD #%d ========\n", 2042 - btv->c.nr, btv->c.nr); 2043 2039 return 0; 2044 2040 } 2045 2041
+1 -12
drivers/media/video/cs5345.c
··· 249 249 .id_table = cs5345_id, 250 250 }; 251 251 252 - static __init int init_cs5345(void) 253 - { 254 - return i2c_add_driver(&cs5345_driver); 255 - } 256 - 257 - static __exit void exit_cs5345(void) 258 - { 259 - i2c_del_driver(&cs5345_driver); 260 - } 261 - 262 - module_init(init_cs5345); 263 - module_exit(exit_cs5345); 252 + module_i2c_driver(cs5345_driver);
+1 -12
drivers/media/video/cs53l32a.c
··· 248 248 .id_table = cs53l32a_id, 249 249 }; 250 250 251 - static __init int init_cs53l32a(void) 252 - { 253 - return i2c_add_driver(&cs53l32a_driver); 254 - } 255 - 256 - static __exit void exit_cs53l32a(void) 257 - { 258 - i2c_del_driver(&cs53l32a_driver); 259 - } 260 - 261 - module_init(init_cs53l32a); 262 - module_exit(exit_cs53l32a); 251 + module_i2c_driver(cs53l32a_driver);
+4 -4
drivers/media/video/cx18/cx18-driver.c
··· 38 38 #include "cx18-ioctl.h" 39 39 #include "cx18-controls.h" 40 40 #include "tuner-xc2028.h" 41 - 41 + #include <linux/dma-mapping.h> 42 42 #include <media/tveeprom.h> 43 43 44 44 /* If you have already X v4l cards, then set this to X. This way ··· 75 75 -1, -1, -1, -1, -1, -1, -1, -1 }; 76 76 static unsigned cardtype_c = 1; 77 77 static unsigned tuner_c = 1; 78 - static bool radio_c = 1; 78 + static unsigned radio_c = 1; 79 79 static char pal[] = "--"; 80 80 static char secam[] = "--"; 81 81 static char ntsc[] = "-"; ··· 110 110 int cx18_debug; 111 111 112 112 module_param_array(tuner, int, &tuner_c, 0644); 113 - module_param_array(radio, bool, &radio_c, 0644); 113 + module_param_array(radio, int, &radio_c, 0644); 114 114 module_param_array(cardtype, int, &cardtype_c, 0644); 115 115 module_param_string(pal, pal, sizeof(pal), 0644); 116 116 module_param_string(secam, secam, sizeof(secam), 0644); ··· 812 812 CX18_ERR("Can't enable device %d!\n", cx->instance); 813 813 return -EIO; 814 814 } 815 - if (pci_set_dma_mask(pci_dev, 0xffffffff)) { 815 + if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32))) { 816 816 CX18_ERR("No suitable DMA available, card %d\n", cx->instance); 817 817 return -EIO; 818 818 }
-2
drivers/media/video/cx18/cx18-driver.h
··· 44 44 #include <linux/slab.h> 45 45 #include <asm/byteorder.h> 46 46 47 - #include <linux/dvb/video.h> 48 - #include <linux/dvb/audio.h> 49 47 #include <media/v4l2-common.h> 50 48 #include <media/v4l2-ioctl.h> 51 49 #include <media/v4l2-device.h>
-4
drivers/media/video/cx18/cx18-ioctl.c
··· 1085 1085 struct v4l2_audio audin; 1086 1086 int i; 1087 1087 1088 - CX18_INFO("================= START STATUS CARD #%d " 1089 - "=================\n", cx->instance); 1090 1088 CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name); 1091 1089 if (cx->hw_flags & CX18_HW_TVEEPROM) { 1092 1090 struct tveeprom tv; ··· 1118 1120 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", 1119 1121 (long long)cx->mpg_data_received, 1120 1122 (long long)cx->vbi_data_inserted); 1121 - CX18_INFO("================== END STATUS CARD #%d " 1122 - "==================\n", cx->instance); 1123 1123 return 0; 1124 1124 } 1125 1125
-1
drivers/media/video/cx231xx/cx231xx-417.c
··· 1686 1686 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | 1687 1687 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | 1688 1688 V4L2_CAP_STREAMING | V4L2_CAP_READWRITE), 1689 - .reserved = {0, 0, 0, 0} 1690 1689 }; 1691 1690 static int vidioc_querycap(struct file *file, void *priv, 1692 1691 struct v4l2_capability *cap)
-1
drivers/media/video/cx231xx/cx231xx-cards.c
··· 861 861 kfree(dev->sliced_cc_mode.alt_max_pkt_size); 862 862 kfree(dev->ts1_mode.alt_max_pkt_size); 863 863 kfree(dev); 864 - dev = NULL; 865 864 } 866 865 867 866 /*
+2 -4
drivers/media/video/cx231xx/cx231xx-video.c
··· 2319 2319 if (dev->state & DEV_DISCONNECTED) { 2320 2320 if (atomic_read(&dev->devlist_count) > 0) { 2321 2321 cx231xx_release_resources(dev); 2322 - kfree(dev); 2323 - dev = NULL; 2322 + fh->dev = NULL; 2324 2323 return 0; 2325 2324 } 2326 2325 return 0; ··· 2349 2350 free the remaining resources */ 2350 2351 if (dev->state & DEV_DISCONNECTED) { 2351 2352 cx231xx_release_resources(dev); 2352 - kfree(dev); 2353 - dev = NULL; 2353 + fh->dev = NULL; 2354 2354 return 0; 2355 2355 } 2356 2356
+7 -2
drivers/media/video/cx25821/cx25821-core.c
··· 1474 1474 .device = 0x8210, 1475 1475 .subvendor = 0x14f1, 1476 1476 .subdevice = 0x0920, 1477 - }, 1478 - { 1477 + }, { 1478 + /* CX25821 No Brand */ 1479 + .vendor = 0x14f1, 1480 + .device = 0x8210, 1481 + .subvendor = 0x0000, 1482 + .subdevice = 0x0000, 1483 + }, { 1479 1484 /* --- end of list --- */ 1480 1485 } 1481 1486 };
+1 -12
drivers/media/video/cx25840/cx25840-core.c
··· 5301 5301 .id_table = cx25840_id, 5302 5302 }; 5303 5303 5304 - static __init int init_cx25840(void) 5305 - { 5306 - return i2c_add_driver(&cx25840_driver); 5307 - } 5308 - 5309 - static __exit void exit_cx25840(void) 5310 - { 5311 - i2c_del_driver(&cx25840_driver); 5312 - } 5313 - 5314 - module_init(init_cx25840); 5315 - module_exit(exit_cx25840); 5304 + module_i2c_driver(cx25840_driver);
-2
drivers/media/video/davinci/vpif.h
··· 18 18 19 19 #include <linux/io.h> 20 20 #include <linux/videodev2.h> 21 - #include <mach/hardware.h> 22 - #include <mach/dm646x.h> 23 21 #include <media/davinci/vpif_types.h> 24 22 25 23 /* Maximum channel allowed */
-2
drivers/media/video/davinci/vpif_display.c
··· 39 39 #include <media/v4l2-ioctl.h> 40 40 #include <media/v4l2-chip-ident.h> 41 41 42 - #include <mach/dm646x.h> 43 - 44 42 #include "vpif_display.h" 45 43 #include "vpif.h" 46 44
+98 -16
drivers/media/video/em28xx/em28xx-cards.c
··· 353 353 }; 354 354 #endif 355 355 356 + /* 1b80:e425 MaxMedia UB425-TC 357 + * GPIO_6 - demod reset, 0=active 358 + * GPIO_7 - LED, 0=active 359 + */ 360 + static struct em28xx_reg_seq maxmedia_ub425_tc[] = { 361 + {EM2874_R80_GPIO, 0x83, 0xff, 100}, 362 + {EM2874_R80_GPIO, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */ 363 + {EM2874_R80_GPIO, 0x43, 0xff, 000}, /* GPIO_7 = 0 */ 364 + {-1, -1, -1, -1}, 365 + }; 366 + 367 + /* 2304:0242 PCTV QuatroStick (510e) 368 + * GPIO_2: decoder reset, 0=active 369 + * GPIO_4: decoder suspend, 0=active 370 + * GPIO_6: demod reset, 0=active 371 + * GPIO_7: LED, 1=active 372 + */ 373 + static struct em28xx_reg_seq pctv_510e[] = { 374 + {EM2874_R80_GPIO, 0x10, 0xff, 100}, 375 + {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ 376 + {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ 377 + { -1, -1, -1, -1}, 378 + }; 379 + 380 + /* 2013:0251 PCTV QuatroStick nano (520e) 381 + * GPIO_2: decoder reset, 0=active 382 + * GPIO_4: decoder suspend, 0=active 383 + * GPIO_6: demod reset, 0=active 384 + * GPIO_7: LED, 1=active 385 + */ 386 + static struct em28xx_reg_seq pctv_520e[] = { 387 + {EM2874_R80_GPIO, 0x10, 0xff, 100}, 388 + {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ 389 + {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ 390 + {EM2874_R80_GPIO, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */ 391 + { -1, -1, -1, -1}, 392 + }; 393 + 356 394 /* 357 395 * Board definitions 358 396 */ ··· 1946 1908 .amux = EM28XX_AMUX_LINE_IN, 1947 1909 } }, 1948 1910 }, 1911 + /* 1b80:e425 MaxMedia UB425-TC 1912 + * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 */ 1913 + [EM2874_BOARD_MAXMEDIA_UB425_TC] = { 1914 + .name = "MaxMedia UB425-TC", 1915 + .tuner_type = TUNER_ABSENT, 1916 + .tuner_gpio = maxmedia_ub425_tc, 1917 + .has_dvb = 1, 1918 + .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | 1919 + EM28XX_I2C_CLK_WAIT_ENABLE | 1920 + EM28XX_I2C_FREQ_400_KHZ, 1921 + }, 1922 + /* 2304:0242 PCTV QuatroStick (510e) 1923 + * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ 1924 + [EM2884_BOARD_PCTV_510E] = { 1925 + .name = "PCTV QuatroStick (510e)", 1926 + .tuner_type = TUNER_ABSENT, 1927 + .tuner_gpio = pctv_510e, 1928 + .has_dvb = 1, 1929 + .ir_codes = RC_MAP_PINNACLE_PCTV_HD, 1930 + .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | 1931 + EM28XX_I2C_CLK_WAIT_ENABLE | 1932 + EM28XX_I2C_FREQ_400_KHZ, 1933 + }, 1934 + /* 2013:0251 PCTV QuatroStick nano (520e) 1935 + * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ 1936 + [EM2884_BOARD_PCTV_520E] = { 1937 + .name = "PCTV QuatroStick nano (520e)", 1938 + .tuner_type = TUNER_ABSENT, 1939 + .tuner_gpio = pctv_520e, 1940 + .has_dvb = 1, 1941 + .ir_codes = RC_MAP_PINNACLE_PCTV_HD, 1942 + .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | 1943 + EM28XX_I2C_CLK_WAIT_ENABLE | 1944 + EM28XX_I2C_FREQ_400_KHZ, 1945 + }, 1949 1946 }; 1950 1947 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); 1951 1948 ··· 2132 2059 .driver_info = EM2860_BOARD_HT_VIDBOX_NW03 }, 2133 2060 { USB_DEVICE(0x1b80, 0xe309), /* Sveon STV40 */ 2134 2061 .driver_info = EM2860_BOARD_EASYCAP }, 2062 + { USB_DEVICE(0x1b80, 0xe425), 2063 + .driver_info = EM2874_BOARD_MAXMEDIA_UB425_TC }, 2064 + { USB_DEVICE(0x2304, 0x0242), 2065 + .driver_info = EM2884_BOARD_PCTV_510E }, 2066 + { USB_DEVICE(0x2013, 0x0251), 2067 + .driver_info = EM2884_BOARD_PCTV_520E }, 2135 2068 { }, 2136 2069 }; 2137 2070 MODULE_DEVICE_TABLE(usb, em28xx_id_table); ··· 3201 3122 int i, nr; 3202 3123 const int ifnum = interface->altsetting[0].desc.bInterfaceNumber; 3203 3124 char *speed; 3204 - char descr[255] = ""; 3205 3125 3206 3126 udev = usb_get_dev(interface_to_usbdev(interface)); 3207 3127 ··· 3305 3227 speed = "unknown"; 3306 3228 } 3307 3229 3308 - if (udev->manufacturer) 3309 - strlcpy(descr, udev->manufacturer, sizeof(descr)); 3310 - 3311 - if (udev->product) { 3312 - if (*descr) 3313 - strlcat(descr, " ", sizeof(descr)); 3314 - strlcat(descr, udev->product, sizeof(descr)); 3315 - } 3316 - 3317 - if (*descr) 3318 - strlcat(descr, " ", sizeof(descr)); 3319 - 3320 3230 printk(KERN_INFO DRIVER_NAME 3321 - ": New device %s@ %s Mbps (%04x:%04x, interface %d, class %d)\n", 3322 - descr, 3231 + ": New device %s %s @ %s Mbps " 3232 + "(%04x:%04x, interface %d, class %d)\n", 3233 + udev->manufacturer ? udev->manufacturer : "", 3234 + udev->product ? udev->product : "", 3323 3235 speed, 3324 3236 le16_to_cpu(udev->descriptor.idVendor), 3325 3237 le16_to_cpu(udev->descriptor.idProduct), ··· 3373 3305 retval = em28xx_init_dev(dev, udev, interface, nr); 3374 3306 if (retval) { 3375 3307 goto unlock_and_free; 3308 + } 3309 + 3310 + if (has_dvb) { 3311 + /* pre-allocate DVB isoc transfer buffers */ 3312 + retval = em28xx_alloc_isoc(dev, EM28XX_DIGITAL_MODE, 3313 + EM28XX_DVB_MAX_PACKETS, 3314 + EM28XX_DVB_NUM_BUFS, 3315 + dev->dvb_max_pkt_size); 3316 + if (retval) { 3317 + goto unlock_and_free; 3318 + } 3376 3319 } 3377 3320 3378 3321 request_modules(dev); ··· 3458 3379 video_device_node_name(dev->vdev)); 3459 3380 3460 3381 dev->state |= DEV_MISCONFIGURED; 3461 - em28xx_uninit_isoc(dev); 3382 + em28xx_uninit_isoc(dev, dev->mode); 3462 3383 dev->state |= DEV_DISCONNECTED; 3463 3384 wake_up_interruptible(&dev->wait_frame); 3464 3385 wake_up_interruptible(&dev->wait_stream); ··· 3466 3387 dev->state |= DEV_DISCONNECTED; 3467 3388 em28xx_release_resources(dev); 3468 3389 } 3390 + 3391 + /* free DVB isoc buffers */ 3392 + em28xx_uninit_isoc(dev, EM28XX_DIGITAL_MODE); 3469 3393 3470 3394 mutex_unlock(&dev->lock); 3471 3395
+96 -49
drivers/media/video/em28xx/em28xx-core.c
··· 666 666 667 667 return rc; 668 668 } 669 + EXPORT_SYMBOL_GPL(em28xx_capture_start); 669 670 670 671 int em28xx_vbi_supported(struct em28xx *dev) 671 672 { ··· 962 961 /* 963 962 * Stop and Deallocate URBs 964 963 */ 965 - void em28xx_uninit_isoc(struct em28xx *dev) 964 + void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode) 966 965 { 967 966 struct urb *urb; 967 + struct em28xx_usb_isoc_bufs *isoc_bufs; 968 968 int i; 969 969 970 - em28xx_isocdbg("em28xx: called em28xx_uninit_isoc\n"); 970 + em28xx_isocdbg("em28xx: called em28xx_uninit_isoc in mode %d\n", mode); 971 + 972 + if (mode == EM28XX_DIGITAL_MODE) 973 + isoc_bufs = &dev->isoc_ctl.digital_bufs; 974 + else 975 + isoc_bufs = &dev->isoc_ctl.analog_bufs; 971 976 972 977 dev->isoc_ctl.nfields = -1; 973 - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { 974 - urb = dev->isoc_ctl.urb[i]; 978 + for (i = 0; i < isoc_bufs->num_bufs; i++) { 979 + urb = isoc_bufs->urb[i]; 975 980 if (urb) { 976 981 if (!irqs_disabled()) 977 982 usb_kill_urb(urb); 978 983 else 979 984 usb_unlink_urb(urb); 980 985 981 - if (dev->isoc_ctl.transfer_buffer[i]) { 986 + if (isoc_bufs->transfer_buffer[i]) { 982 987 usb_free_coherent(dev->udev, 983 988 urb->transfer_buffer_length, 984 - dev->isoc_ctl.transfer_buffer[i], 989 + isoc_bufs->transfer_buffer[i], 985 990 urb->transfer_dma); 986 991 } 987 992 usb_free_urb(urb); 988 - dev->isoc_ctl.urb[i] = NULL; 993 + isoc_bufs->urb[i] = NULL; 989 994 } 990 - dev->isoc_ctl.transfer_buffer[i] = NULL; 995 + isoc_bufs->transfer_buffer[i] = NULL; 991 996 } 992 997 993 - kfree(dev->isoc_ctl.urb); 994 - kfree(dev->isoc_ctl.transfer_buffer); 998 + kfree(isoc_bufs->urb); 999 + kfree(isoc_bufs->transfer_buffer); 995 1000 996 - dev->isoc_ctl.urb = NULL; 997 - dev->isoc_ctl.transfer_buffer = NULL; 998 - dev->isoc_ctl.num_bufs = 0; 1001 + isoc_bufs->urb = NULL; 1002 + isoc_bufs->transfer_buffer = NULL; 1003 + isoc_bufs->num_bufs = 0; 999 1004 1000 1005 em28xx_capture_start(dev, 0); 1001 1006 } 1002 1007 EXPORT_SYMBOL_GPL(em28xx_uninit_isoc); 1003 1008 1004 1009 /* 1005 - * Allocate URBs and start IRQ 1010 + * Allocate URBs 1006 1011 */ 1007 - int em28xx_init_isoc(struct em28xx *dev, int max_packets, 1008 - int num_bufs, int max_pkt_size, 1009 - int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) 1012 + int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode, 1013 + int max_packets, int num_bufs, int max_pkt_size) 1010 1014 { 1011 - struct em28xx_dmaqueue *dma_q = &dev->vidq; 1012 - struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; 1015 + struct em28xx_usb_isoc_bufs *isoc_bufs; 1013 1016 int i; 1014 1017 int sb_size, pipe; 1015 1018 struct urb *urb; 1016 1019 int j, k; 1017 - int rc; 1018 1020 1019 - em28xx_isocdbg("em28xx: called em28xx_prepare_isoc\n"); 1021 + em28xx_isocdbg("em28xx: called em28xx_alloc_isoc in mode %d\n", mode); 1022 + 1023 + if (mode == EM28XX_DIGITAL_MODE) 1024 + isoc_bufs = &dev->isoc_ctl.digital_bufs; 1025 + else 1026 + isoc_bufs = &dev->isoc_ctl.analog_bufs; 1020 1027 1021 1028 /* De-allocates all pending stuff */ 1022 - em28xx_uninit_isoc(dev); 1029 + em28xx_uninit_isoc(dev, mode); 1023 1030 1024 - dev->isoc_ctl.isoc_copy = isoc_copy; 1025 - dev->isoc_ctl.num_bufs = num_bufs; 1031 + isoc_bufs->num_bufs = num_bufs; 1026 1032 1027 - dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); 1028 - if (!dev->isoc_ctl.urb) { 1033 + isoc_bufs->urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); 1034 + if (!isoc_bufs->urb) { 1029 1035 em28xx_errdev("cannot alloc memory for usb buffers\n"); 1030 1036 return -ENOMEM; 1031 1037 } 1032 1038 1033 - dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, 1034 - GFP_KERNEL); 1035 - if (!dev->isoc_ctl.transfer_buffer) { 1039 + isoc_bufs->transfer_buffer = kzalloc(sizeof(void *)*num_bufs, 1040 + GFP_KERNEL); 1041 + if (!isoc_bufs->transfer_buffer) { 1036 1042 em28xx_errdev("cannot allocate memory for usb transfer\n"); 1037 - kfree(dev->isoc_ctl.urb); 1043 + kfree(isoc_bufs->urb); 1038 1044 return -ENOMEM; 1039 1045 } 1040 1046 1041 - dev->isoc_ctl.max_pkt_size = max_pkt_size; 1047 + isoc_bufs->max_pkt_size = max_pkt_size; 1048 + isoc_bufs->num_packets = max_packets; 1042 1049 dev->isoc_ctl.vid_buf = NULL; 1043 1050 dev->isoc_ctl.vbi_buf = NULL; 1044 1051 1045 - sb_size = max_packets * dev->isoc_ctl.max_pkt_size; 1052 + sb_size = isoc_bufs->num_packets * isoc_bufs->max_pkt_size; 1046 1053 1047 1054 /* allocate urbs and transfer buffers */ 1048 - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { 1049 - urb = usb_alloc_urb(max_packets, GFP_KERNEL); 1055 + for (i = 0; i < isoc_bufs->num_bufs; i++) { 1056 + urb = usb_alloc_urb(isoc_bufs->num_packets, GFP_KERNEL); 1050 1057 if (!urb) { 1051 1058 em28xx_err("cannot alloc isoc_ctl.urb %i\n", i); 1052 - em28xx_uninit_isoc(dev); 1059 + em28xx_uninit_isoc(dev, mode); 1053 1060 return -ENOMEM; 1054 1061 } 1055 - dev->isoc_ctl.urb[i] = urb; 1062 + isoc_bufs->urb[i] = urb; 1056 1063 1057 - dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev, 1064 + isoc_bufs->transfer_buffer[i] = usb_alloc_coherent(dev->udev, 1058 1065 sb_size, GFP_KERNEL, &urb->transfer_dma); 1059 - if (!dev->isoc_ctl.transfer_buffer[i]) { 1066 + if (!isoc_bufs->transfer_buffer[i]) { 1060 1067 em28xx_err("unable to allocate %i bytes for transfer" 1061 1068 " buffer %i%s\n", 1062 1069 sb_size, i, 1063 1070 in_interrupt() ? " while in int" : ""); 1064 - em28xx_uninit_isoc(dev); 1071 + em28xx_uninit_isoc(dev, mode); 1065 1072 return -ENOMEM; 1066 1073 } 1067 - memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size); 1074 + memset(isoc_bufs->transfer_buffer[i], 0, sb_size); 1068 1075 1069 1076 /* FIXME: this is a hack - should be 1070 1077 'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK' 1071 1078 should also be using 'desc.bInterval' 1072 1079 */ 1073 1080 pipe = usb_rcvisocpipe(dev->udev, 1074 - dev->mode == EM28XX_ANALOG_MODE ? 1081 + mode == EM28XX_ANALOG_MODE ? 1075 1082 EM28XX_EP_ANALOG : EM28XX_EP_DIGITAL); 1076 1083 1077 1084 usb_fill_int_urb(urb, dev->udev, pipe, 1078 - dev->isoc_ctl.transfer_buffer[i], sb_size, 1085 + isoc_bufs->transfer_buffer[i], sb_size, 1079 1086 em28xx_irq_callback, dev, 1); 1080 1087 1081 - urb->number_of_packets = max_packets; 1088 + urb->number_of_packets = isoc_bufs->num_packets; 1082 1089 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 1083 1090 1084 1091 k = 0; 1085 - for (j = 0; j < max_packets; j++) { 1092 + for (j = 0; j < isoc_bufs->num_packets; j++) { 1086 1093 urb->iso_frame_desc[j].offset = k; 1087 1094 urb->iso_frame_desc[j].length = 1088 - dev->isoc_ctl.max_pkt_size; 1089 - k += dev->isoc_ctl.max_pkt_size; 1095 + isoc_bufs->max_pkt_size; 1096 + k += isoc_bufs->max_pkt_size; 1090 1097 } 1098 + } 1099 + 1100 + return 0; 1101 + } 1102 + EXPORT_SYMBOL_GPL(em28xx_alloc_isoc); 1103 + 1104 + /* 1105 + * Allocate URBs and start IRQ 1106 + */ 1107 + int em28xx_init_isoc(struct em28xx *dev, enum em28xx_mode mode, 1108 + int max_packets, int num_bufs, int max_pkt_size, 1109 + int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) 1110 + { 1111 + struct em28xx_dmaqueue *dma_q = &dev->vidq; 1112 + struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; 1113 + struct em28xx_usb_isoc_bufs *isoc_bufs; 1114 + int i; 1115 + int rc; 1116 + int alloc; 1117 + 1118 + em28xx_isocdbg("em28xx: called em28xx_init_isoc in mode %d\n", mode); 1119 + 1120 + dev->isoc_ctl.isoc_copy = isoc_copy; 1121 + 1122 + if (mode == EM28XX_DIGITAL_MODE) { 1123 + isoc_bufs = &dev->isoc_ctl.digital_bufs; 1124 + /* no need to free/alloc isoc buffers in digital mode */ 1125 + alloc = 0; 1126 + } else { 1127 + isoc_bufs = &dev->isoc_ctl.analog_bufs; 1128 + alloc = 1; 1129 + } 1130 + 1131 + if (alloc) { 1132 + rc = em28xx_alloc_isoc(dev, mode, max_packets, 1133 + num_bufs, max_pkt_size); 1134 + if (rc) 1135 + return rc; 1091 1136 } 1092 1137 1093 1138 init_waitqueue_head(&dma_q->wq); ··· 1142 1095 em28xx_capture_start(dev, 1); 1143 1096 1144 1097 /* submit urbs and enables IRQ */ 1145 - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { 1146 - rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC); 1098 + for (i = 0; i < isoc_bufs->num_bufs; i++) { 1099 + rc = usb_submit_urb(isoc_bufs->urb[i], GFP_ATOMIC); 1147 1100 if (rc) { 1148 1101 em28xx_err("submit of urb %i failed (error=%i)\n", i, 1149 1102 rc); 1150 - em28xx_uninit_isoc(dev); 1103 + em28xx_uninit_isoc(dev, mode); 1151 1104 return rc; 1152 1105 } 1153 1106 }
+88 -8
drivers/media/video/em28xx/em28xx-dvb.c
··· 61 61 printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ 62 62 } while (0) 63 63 64 - #define EM28XX_DVB_NUM_BUFS 5 65 - #define EM28XX_DVB_MAX_PACKETS 64 66 - 67 64 struct em28xx_dvb { 68 65 struct dvb_frontend *fe[2]; 69 66 ··· 169 172 max_dvb_packet_size = dev->dvb_max_pkt_size; 170 173 if (max_dvb_packet_size < 0) 171 174 return max_dvb_packet_size; 172 - dprintk(1, "Using %d buffers each with %d bytes\n", 175 + dprintk(1, "Using %d buffers each with %d x %d bytes\n", 173 176 EM28XX_DVB_NUM_BUFS, 177 + EM28XX_DVB_MAX_PACKETS, 174 178 max_dvb_packet_size); 175 179 176 - return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, 177 - EM28XX_DVB_NUM_BUFS, max_dvb_packet_size, 178 - em28xx_dvb_isoc_copy); 180 + return em28xx_init_isoc(dev, EM28XX_DIGITAL_MODE, 181 + EM28XX_DVB_MAX_PACKETS, EM28XX_DVB_NUM_BUFS, 182 + max_dvb_packet_size, em28xx_dvb_isoc_copy); 179 183 } 180 184 181 185 static int em28xx_stop_streaming(struct em28xx_dvb *dvb) 182 186 { 183 187 struct em28xx *dev = dvb->adapter.priv; 184 188 185 - em28xx_uninit_isoc(dev); 189 + em28xx_capture_start(dev, 0); 186 190 187 191 em28xx_set_mode(dev, EM28XX_SUSPEND); 188 192 ··· 325 327 .chunk_size = 56, 326 328 }; 327 329 330 + struct drxk_config maxmedia_ub425_tc_drxk = { 331 + .adr = 0x29, 332 + .single_master = 1, 333 + .no_i2c_bridge = 1, 334 + }; 335 + 336 + struct drxk_config pctv_520e_drxk = { 337 + .adr = 0x29, 338 + .single_master = 1, 339 + .microcode_name = "dvb-demod-drxk-pctv.fw", 340 + .chunk_size = 58, 341 + }; 342 + 328 343 static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 329 344 { 330 345 struct em28xx_dvb *dvb = fe->sec_priv; ··· 469 458 for (i = 0; i < ARRAY_SIZE(regs); i++) 470 459 i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); 471 460 em28xx_gpio_set(dev, terratec_h5_end); 461 + }; 462 + 463 + static void pctv_520e_init(struct em28xx *dev) 464 + { 465 + /* 466 + * Init TDA8295(?) analog demodulator. Looks like I2C traffic to 467 + * digital demodulator and tuner are routed via TDA8295. 468 + */ 469 + int i; 470 + struct { 471 + unsigned char r[4]; 472 + int len; 473 + } regs[] = { 474 + {{ 0x06, 0x02, 0x00, 0x31 }, 4}, 475 + {{ 0x01, 0x02 }, 2}, 476 + {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, 477 + {{ 0x01, 0x00 }, 2}, 478 + {{ 0x01, 0x00, 0xff, 0xaf }, 4}, 479 + {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, 480 + {{ 0x01, 0x00 }, 2}, 481 + {{ 0x01, 0x00, 0x73, 0xaf }, 4}, 482 + }; 483 + 484 + dev->i2c_client.addr = 0x82 >> 1; /* 0x41 */ 485 + 486 + for (i = 0; i < ARRAY_SIZE(regs); i++) 487 + i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); 472 488 }; 473 489 474 490 static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) ··· 975 937 if (dvb->fe[0]) 976 938 dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap, 977 939 &em28xx_a8293_config); 940 + break; 941 + case EM2874_BOARD_MAXMEDIA_UB425_TC: 942 + /* attach demodulator */ 943 + dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk, 944 + &dev->i2c_adap); 945 + 946 + if (dvb->fe[0]) { 947 + /* disable I2C-gate */ 948 + dvb->fe[0]->ops.i2c_gate_ctrl = NULL; 949 + 950 + /* attach tuner */ 951 + if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], 952 + &dev->i2c_adap, 0x60)) { 953 + dvb_frontend_detach(dvb->fe[0]); 954 + result = -EINVAL; 955 + goto out_free; 956 + } 957 + } 958 + 959 + /* TODO: we need drx-3913k firmware in order to support DVB-T */ 960 + em28xx_info("MaxMedia UB425-TC: only DVB-C supported by that " \ 961 + "driver version\n"); 962 + 963 + break; 964 + case EM2884_BOARD_PCTV_510E: 965 + case EM2884_BOARD_PCTV_520E: 966 + pctv_520e_init(dev); 967 + 968 + /* attach demodulator */ 969 + dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk, 970 + &dev->i2c_adap); 971 + 972 + if (dvb->fe[0]) { 973 + /* attach tuner */ 974 + if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, 975 + &dev->i2c_adap, 976 + &em28xx_cxd2820r_tda18271_config)) { 977 + dvb_frontend_detach(dvb->fe[0]); 978 + result = -EINVAL; 979 + goto out_free; 980 + } 981 + } 978 982 break; 979 983 default: 980 984 em28xx_errdev("/2: The frontend of your DVB/ATSC card"
-8
drivers/media/video/em28xx/em28xx-i2c.c
··· 41 41 module_param(i2c_debug, int, 0644); 42 42 MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); 43 43 44 - 45 - #define dprintk1(lvl, fmt, args...) \ 46 - do { \ 47 - if (i2c_debug >= lvl) { \ 48 - printk(fmt, ##args); \ 49 - } \ 50 - } while (0) 51 - 52 44 #define dprintk2(lvl, fmt, args...) \ 53 45 do { \ 54 46 if (i2c_debug >= lvl) { \
+6 -4
drivers/media/video/em28xx/em28xx-video.c
··· 760 760 goto fail; 761 761 } 762 762 763 - if (!dev->isoc_ctl.num_bufs) 763 + if (!dev->isoc_ctl.analog_bufs.num_bufs) 764 764 urb_init = 1; 765 765 766 766 if (urb_init) { 767 767 if (em28xx_vbi_supported(dev) == 1) 768 - rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, 768 + rc = em28xx_init_isoc(dev, EM28XX_ANALOG_MODE, 769 + EM28XX_NUM_PACKETS, 769 770 EM28XX_NUM_BUFS, 770 771 dev->max_pkt_size, 771 772 em28xx_isoc_copy_vbi); 772 773 else 773 - rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, 774 + rc = em28xx_init_isoc(dev, EM28XX_ANALOG_MODE, 775 + EM28XX_NUM_PACKETS, 774 776 EM28XX_NUM_BUFS, 775 777 dev->max_pkt_size, 776 778 em28xx_isoc_copy); ··· 2269 2267 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); 2270 2268 2271 2269 /* do this before setting alternate! */ 2272 - em28xx_uninit_isoc(dev); 2270 + em28xx_uninit_isoc(dev, EM28XX_ANALOG_MODE); 2273 2271 em28xx_set_mode(dev, EM28XX_SUSPEND); 2274 2272 2275 2273 /* set alternate 0 */
+22 -7
drivers/media/video/em28xx/em28xx.h
··· 125 125 #define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 126 126 #define EM2884_BOARD_CINERGY_HTC_STICK 82 127 127 #define EM2860_BOARD_HT_VIDBOX_NW03 83 128 + #define EM2874_BOARD_MAXMEDIA_UB425_TC 84 129 + #define EM2884_BOARD_PCTV_510E 85 130 + #define EM2884_BOARD_PCTV_520E 86 128 131 129 132 /* Limits minimum and default number of buffers */ 130 133 #define EM28XX_MIN_BUF 4 ··· 154 151 155 152 /* number of buffers for isoc transfers */ 156 153 #define EM28XX_NUM_BUFS 5 154 + #define EM28XX_DVB_NUM_BUFS 5 157 155 158 156 /* number of packets for each buffer 159 157 windows requests only 64 packets .. so we better do the same 160 158 this is what I found out for all alternate numbers there! 161 159 */ 162 160 #define EM28XX_NUM_PACKETS 64 161 + #define EM28XX_DVB_MAX_PACKETS 64 163 162 164 163 #define EM28XX_INTERLACED_DEFAULT 1 165 164 ··· 202 197 203 198 struct em28xx; 204 199 205 - struct em28xx_usb_isoc_ctl { 200 + struct em28xx_usb_isoc_bufs { 206 201 /* max packet size of isoc transaction */ 207 202 int max_pkt_size; 203 + 204 + /* number of packets in each buffer */ 205 + int num_packets; 208 206 209 207 /* number of allocated urbs */ 210 208 int num_bufs; ··· 217 209 218 210 /* transfer buffers for isoc transfer */ 219 211 char **transfer_buffer; 212 + }; 213 + 214 + struct em28xx_usb_isoc_ctl { 215 + /* isoc transfer buffers for analog mode */ 216 + struct em28xx_usb_isoc_bufs analog_bufs; 217 + 218 + /* isoc transfer buffers for digital mode */ 219 + struct em28xx_usb_isoc_bufs digital_bufs; 220 220 221 221 /* Last buffer command and region */ 222 222 u8 cmd; ··· 616 600 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ 617 601 int dvb_alt; /* alternate for DVB */ 618 602 unsigned int dvb_max_pkt_size; /* wMaxPacketSize for DVB */ 619 - struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ 620 - char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc 621 - transfer */ 622 603 char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ 623 604 624 605 /* helper funcs that call usb_control_msg */ ··· 689 676 int em28xx_set_outfmt(struct em28xx *dev); 690 677 int em28xx_resolution_set(struct em28xx *dev); 691 678 int em28xx_set_alternate(struct em28xx *dev); 692 - int em28xx_init_isoc(struct em28xx *dev, int max_packets, 693 - int num_bufs, int max_pkt_size, 679 + int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode, 680 + int max_packets, int num_bufs, int max_pkt_size); 681 + int em28xx_init_isoc(struct em28xx *dev, enum em28xx_mode mode, 682 + int max_packets, int num_bufs, int max_pkt_size, 694 683 int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); 695 - void em28xx_uninit_isoc(struct em28xx *dev); 684 + void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode); 696 685 int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev); 697 686 int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); 698 687 int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
+1 -1
drivers/media/video/gspca/gl860/Makefile
··· 6 6 gl860-ov9655.o \ 7 7 gl860-mi2020.o 8 8 9 - ccflags-y += -Idrivers/media/video/gspca 9 + ccflags-y += -I$(srctree)/drivers/media/video/gspca 10 10
+1 -1
drivers/media/video/gspca/m5602/Makefile
··· 8 8 m5602_s5k83a.o \ 9 9 m5602_s5k4aa.o 10 10 11 - ccflags-y += -Idrivers/media/video/gspca 11 + ccflags-y += -I$(srctree)/drivers/media/video/gspca
+39 -8
drivers/media/video/gspca/ov534_9.c
··· 1107 1107 { 1108 1108 struct sd *sd = (struct sd *) gspca_dev; 1109 1109 u8 val; 1110 + s8 sval; 1110 1111 1111 1112 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS)) 1112 1113 return; 1113 - val = sd->ctrls[BRIGHTNESS].val; 1114 - if (val < 8) 1115 - val = 15 - val; /* f .. 8 */ 1116 - else 1117 - val = val - 8; /* 0 .. 7 */ 1118 - sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ 1119 - 0x0f | (val << 4)); 1114 + if (sd->sensor == SENSOR_OV562x) { 1115 + sval = sd->ctrls[BRIGHTNESS].val; 1116 + val = 0x76; 1117 + val += sval; 1118 + sccb_write(gspca_dev, 0x24, val); 1119 + val = 0x6a; 1120 + val += sval; 1121 + sccb_write(gspca_dev, 0x25, val); 1122 + if (sval < -40) 1123 + val = 0x71; 1124 + else if (sval < 20) 1125 + val = 0x94; 1126 + else 1127 + val = 0xe6; 1128 + sccb_write(gspca_dev, 0x26, val); 1129 + } else { 1130 + val = sd->ctrls[BRIGHTNESS].val; 1131 + if (val < 8) 1132 + val = 15 - val; /* f .. 8 */ 1133 + else 1134 + val = val - 8; /* 0 .. 7 */ 1135 + sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ 1136 + 0x0f | (val << 4)); 1137 + } 1120 1138 } 1121 1139 1122 1140 static void setcontrast(struct gspca_dev *gspca_dev) ··· 1357 1339 reg_w(gspca_dev, 0x56, 0x17); 1358 1340 } else if ((sensor_id & 0xfff0) == 0x5620) { 1359 1341 sd->sensor = SENSOR_OV562x; 1342 + gspca_dev->ctrl_dis = (1 << CONTRAST) | 1343 + (1 << AUTOGAIN) | 1344 + (1 << EXPOSURE) | 1345 + (1 << SHARPNESS) | 1346 + (1 << SATUR) | 1347 + (1 << LIGHTFREQ); 1360 1348 1349 + sd->ctrls[BRIGHTNESS].min = -90; 1350 + sd->ctrls[BRIGHTNESS].max = 90; 1351 + sd->ctrls[BRIGHTNESS].def = 0; 1361 1352 gspca_dev->cam.cam_mode = ov562x_mode; 1362 1353 gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); 1363 1354 ··· 1387 1360 { 1388 1361 struct sd *sd = (struct sd *) gspca_dev; 1389 1362 1390 - if (sd->sensor == SENSOR_OV971x || sd->sensor == SENSOR_OV562x) 1363 + if (sd->sensor == SENSOR_OV971x) 1391 1364 return gspca_dev->usb_err; 1365 + else if (sd->sensor == SENSOR_OV562x) { 1366 + setbrightness(gspca_dev); 1367 + return gspca_dev->usb_err; 1368 + } 1392 1369 switch (gspca_dev->curr_mode) { 1393 1370 case QVGA_MODE: /* 320x240 */ 1394 1371 sccb_w_array(gspca_dev, ov965x_start_1_vga,
+164 -417
drivers/media/video/gspca/pac7302.c
··· 1 1 /* 2 - * Pixart PAC7302 library 3 - * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li 2 + * Pixart PAC7302 driver 4 3 * 5 - * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 + * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr> 5 + * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li 6 6 * 7 7 * Separated from Pixart PAC7311 library by Márton Németh 8 8 * Camera button input handling by Márton Németh <nm127@freemail.hu> ··· 63 63 64 64 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 65 65 66 - #define MODULE_NAME "pac7302" 67 - 68 66 #include <linux/input.h> 69 67 #include <media/v4l2-chip-ident.h> 70 68 #include "gspca.h" 69 + /* Include pac common sof detection functions */ 70 + #include "pac_common.h" 71 71 72 - MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); 72 + MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, " 73 + "Thomas Kaiser thomas@kaiser-linux.li"); 73 74 MODULE_DESCRIPTION("Pixart PAC7302"); 74 75 MODULE_LICENSE("GPL"); 76 + 77 + enum e_ctrl { 78 + BRIGHTNESS, 79 + CONTRAST, 80 + COLORS, 81 + WHITE_BALANCE, 82 + RED_BALANCE, 83 + BLUE_BALANCE, 84 + GAIN, 85 + AUTOGAIN, 86 + EXPOSURE, 87 + VFLIP, 88 + HFLIP, 89 + NCTRLS /* number of controls */ 90 + }; 75 91 76 92 /* specific webcam descriptor for pac7302 */ 77 93 struct sd { 78 94 struct gspca_dev gspca_dev; /* !! must be the first item */ 79 95 80 - unsigned char brightness; 81 - unsigned char contrast; 82 - unsigned char colors; 83 - unsigned char white_balance; 84 - unsigned char red_balance; 85 - unsigned char blue_balance; 86 - unsigned char gain; 87 - unsigned char autogain; 88 - unsigned short exposure; 89 - __u8 hflip; 90 - __u8 vflip; 96 + struct gspca_ctrl ctrls[NCTRLS]; 97 + 91 98 u8 flags; 92 99 #define FL_HFLIP 0x01 /* mirrored by default */ 93 100 #define FL_VFLIP 0x02 /* vertical flipped by default */ 94 101 95 102 u8 sof_read; 96 - u8 autogain_ignore_frames; 103 + s8 autogain_ignore_frames; 97 104 98 105 atomic_t avg_lum; 99 106 }; 100 107 101 108 /* V4L2 controls supported by the driver */ 102 - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 103 - static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 104 - static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 105 - static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 106 - static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 107 - static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 108 - static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); 109 - static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); 110 - static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val); 111 - static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val); 112 - static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val); 113 - static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val); 114 - static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 115 - static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 116 - static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 117 - static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 118 - static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 119 - static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 120 - static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 121 - static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 122 - static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 123 - static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 109 + static void setbrightcont(struct gspca_dev *gspca_dev); 110 + static void setcolors(struct gspca_dev *gspca_dev); 111 + static void setwhitebalance(struct gspca_dev *gspca_dev); 112 + static void setredbalance(struct gspca_dev *gspca_dev); 113 + static void setbluebalance(struct gspca_dev *gspca_dev); 114 + static void setgain(struct gspca_dev *gspca_dev); 115 + static void setexposure(struct gspca_dev *gspca_dev); 116 + static void setautogain(struct gspca_dev *gspca_dev); 117 + static void sethvflip(struct gspca_dev *gspca_dev); 124 118 125 119 static const struct ctrl sd_ctrls[] = { 126 - { 120 + [BRIGHTNESS] = { 127 121 { 128 122 .id = V4L2_CID_BRIGHTNESS, 129 123 .type = V4L2_CTRL_TYPE_INTEGER, ··· 126 132 #define BRIGHTNESS_MAX 0x20 127 133 .maximum = BRIGHTNESS_MAX, 128 134 .step = 1, 129 - #define BRIGHTNESS_DEF 0x10 130 - .default_value = BRIGHTNESS_DEF, 135 + .default_value = 0x10, 131 136 }, 132 - .set = sd_setbrightness, 133 - .get = sd_getbrightness, 137 + .set_control = setbrightcont 134 138 }, 135 - { 139 + [CONTRAST] = { 136 140 { 137 141 .id = V4L2_CID_CONTRAST, 138 142 .type = V4L2_CTRL_TYPE_INTEGER, ··· 139 147 #define CONTRAST_MAX 255 140 148 .maximum = CONTRAST_MAX, 141 149 .step = 1, 142 - #define CONTRAST_DEF 127 143 - .default_value = CONTRAST_DEF, 150 + .default_value = 127, 144 151 }, 145 - .set = sd_setcontrast, 146 - .get = sd_getcontrast, 152 + .set_control = setbrightcont 147 153 }, 148 - { 154 + [COLORS] = { 149 155 { 150 156 .id = V4L2_CID_SATURATION, 151 157 .type = V4L2_CTRL_TYPE_INTEGER, ··· 152 162 #define COLOR_MAX 255 153 163 .maximum = COLOR_MAX, 154 164 .step = 1, 155 - #define COLOR_DEF 127 156 - .default_value = COLOR_DEF, 165 + .default_value = 127 157 166 }, 158 - .set = sd_setcolors, 159 - .get = sd_getcolors, 167 + .set_control = setcolors 160 168 }, 161 - { 169 + [WHITE_BALANCE] = { 162 170 { 163 171 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, 164 172 .type = V4L2_CTRL_TYPE_INTEGER, ··· 164 176 .minimum = 0, 165 177 .maximum = 255, 166 178 .step = 1, 167 - #define WHITEBALANCE_DEF 4 168 - .default_value = WHITEBALANCE_DEF, 179 + .default_value = 4, 169 180 }, 170 - .set = sd_setwhitebalance, 171 - .get = sd_getwhitebalance, 181 + .set_control = setwhitebalance 172 182 }, 173 - { 183 + [RED_BALANCE] = { 174 184 { 175 185 .id = V4L2_CID_RED_BALANCE, 176 186 .type = V4L2_CTRL_TYPE_INTEGER, ··· 176 190 .minimum = 0, 177 191 .maximum = 3, 178 192 .step = 1, 179 - #define REDBALANCE_DEF 1 180 - .default_value = REDBALANCE_DEF, 193 + .default_value = 1, 181 194 }, 182 - .set = sd_setredbalance, 183 - .get = sd_getredbalance, 195 + .set_control = setredbalance 184 196 }, 185 - { 197 + [BLUE_BALANCE] = { 186 198 { 187 199 .id = V4L2_CID_BLUE_BALANCE, 188 200 .type = V4L2_CTRL_TYPE_INTEGER, ··· 188 204 .minimum = 0, 189 205 .maximum = 3, 190 206 .step = 1, 191 - #define BLUEBALANCE_DEF 1 192 - .default_value = BLUEBALANCE_DEF, 207 + .default_value = 1, 193 208 }, 194 - .set = sd_setbluebalance, 195 - .get = sd_getbluebalance, 209 + .set_control = setbluebalance 196 210 }, 197 - { 211 + [GAIN] = { 198 212 { 199 213 .id = V4L2_CID_GAIN, 200 214 .type = V4L2_CTRL_TYPE_INTEGER, 201 215 .name = "Gain", 202 216 .minimum = 0, 203 - #define GAIN_MAX 255 204 - .maximum = GAIN_MAX, 217 + .maximum = 255, 205 218 .step = 1, 206 219 #define GAIN_DEF 127 207 220 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */ 208 221 .default_value = GAIN_DEF, 209 222 }, 210 - .set = sd_setgain, 211 - .get = sd_getgain, 223 + .set_control = setgain 212 224 }, 213 - { 225 + [EXPOSURE] = { 214 226 { 215 227 .id = V4L2_CID_EXPOSURE, 216 228 .type = V4L2_CTRL_TYPE_INTEGER, ··· 218 238 #define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */ 219 239 .default_value = EXPOSURE_DEF, 220 240 }, 221 - .set = sd_setexposure, 222 - .get = sd_getexposure, 241 + .set_control = setexposure 223 242 }, 224 - { 243 + [AUTOGAIN] = { 225 244 { 226 245 .id = V4L2_CID_AUTOGAIN, 227 246 .type = V4L2_CTRL_TYPE_BOOLEAN, ··· 231 252 #define AUTOGAIN_DEF 1 232 253 .default_value = AUTOGAIN_DEF, 233 254 }, 234 - .set = sd_setautogain, 235 - .get = sd_getautogain, 255 + .set_control = setautogain, 236 256 }, 237 - { 257 + [HFLIP] = { 238 258 { 239 259 .id = V4L2_CID_HFLIP, 240 260 .type = V4L2_CTRL_TYPE_BOOLEAN, ··· 241 263 .minimum = 0, 242 264 .maximum = 1, 243 265 .step = 1, 244 - #define HFLIP_DEF 0 245 - .default_value = HFLIP_DEF, 266 + .default_value = 0, 246 267 }, 247 - .set = sd_sethflip, 248 - .get = sd_gethflip, 268 + .set_control = sethvflip, 249 269 }, 250 - { 270 + [VFLIP] = { 251 271 { 252 272 .id = V4L2_CID_VFLIP, 253 273 .type = V4L2_CTRL_TYPE_BOOLEAN, ··· 253 277 .minimum = 0, 254 278 .maximum = 1, 255 279 .step = 1, 256 - #define VFLIP_DEF 0 257 - .default_value = VFLIP_DEF, 280 + .default_value = 0, 258 281 }, 259 - .set = sd_setvflip, 260 - .get = sd_getvflip, 282 + .set_control = sethvflip 261 283 }, 262 284 }; 263 285 ··· 264 290 .bytesperline = 640, 265 291 .sizeimage = 640 * 480 * 3 / 8 + 590, 266 292 .colorspace = V4L2_COLORSPACE_JPEG, 267 - .priv = 0}, 293 + }, 268 294 }; 269 295 270 296 #define LOAD_PAGE3 255 271 297 #define END_OF_SEQUENCE 0 272 298 273 299 /* pac 7302 */ 274 - static const __u8 init_7302[] = { 300 + static const u8 init_7302[] = { 275 301 /* index,value */ 276 302 0xff, 0x01, /* page 1 */ 277 303 0x78, 0x00, /* deactivate */ 278 304 0xff, 0x01, 279 305 0x78, 0x40, /* led off */ 280 306 }; 281 - static const __u8 start_7302[] = { 307 + static const u8 start_7302[] = { 282 308 /* index, len, [value]* */ 283 309 0xff, 1, 0x00, /* page 0 */ 284 310 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, ··· 293 319 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, 294 320 0x00, 0x54, 0x11, 295 321 0x55, 1, 0x00, 296 - 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, 322 + 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, 297 323 0x6b, 1, 0x00, 298 324 0x6e, 3, 0x08, 0x06, 0x00, 299 325 0x72, 3, 0x00, 0xff, 0x00, ··· 344 370 345 371 #define SKIP 0xaa 346 372 /* page 3 - the value SKIP says skip the index - see reg_w_page() */ 347 - static const __u8 page3_7302[] = { 373 + static const u8 page3_7302[] = { 348 374 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16, 349 375 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 350 376 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ··· 368 394 }; 369 395 370 396 static void reg_w_buf(struct gspca_dev *gspca_dev, 371 - __u8 index, 397 + u8 index, 372 398 const u8 *buffer, int len) 373 399 { 374 400 int ret; ··· 384 410 index, gspca_dev->usb_buf, len, 385 411 500); 386 412 if (ret < 0) { 387 - pr_err("reg_w_buf failed index 0x%02x, error %d\n", 413 + pr_err("reg_w_buf failed i: %02x error %d\n", 388 414 index, ret); 389 415 gspca_dev->usb_err = ret; 390 416 } ··· 392 418 393 419 394 420 static void reg_w(struct gspca_dev *gspca_dev, 395 - __u8 index, 396 - __u8 value) 421 + u8 index, 422 + u8 value) 397 423 { 398 424 int ret; 399 425 ··· 407 433 0, index, gspca_dev->usb_buf, 1, 408 434 500); 409 435 if (ret < 0) { 410 - pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n", 436 + pr_err("reg_w() failed i: %02x v: %02x error %d\n", 411 437 index, value, ret); 412 438 gspca_dev->usb_err = ret; 413 439 } 414 440 } 415 441 416 442 static void reg_w_seq(struct gspca_dev *gspca_dev, 417 - const __u8 *seq, int len) 443 + const u8 *seq, int len) 418 444 { 419 445 while (--len >= 0) { 420 446 reg_w(gspca_dev, seq[0], seq[1]); ··· 424 450 425 451 /* load the beginning of a page */ 426 452 static void reg_w_page(struct gspca_dev *gspca_dev, 427 - const __u8 *page, int len) 453 + const u8 *page, int len) 428 454 { 429 455 int index; 430 456 int ret = 0; ··· 442 468 0, index, gspca_dev->usb_buf, 1, 443 469 500); 444 470 if (ret < 0) { 445 - pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n", 471 + pr_err("reg_w_page() failed i: %02x v: %02x error %d\n", 446 472 index, page[index], ret); 447 473 gspca_dev->usb_err = ret; 448 474 break; ··· 452 478 453 479 /* output a variable sequence */ 454 480 static void reg_w_var(struct gspca_dev *gspca_dev, 455 - const __u8 *seq, 456 - const __u8 *page3, unsigned int page3_len) 481 + const u8 *seq, 482 + const u8 *page3, unsigned int page3_len) 457 483 { 458 484 int index, len; 459 485 ··· 467 493 reg_w_page(gspca_dev, page3, page3_len); 468 494 break; 469 495 default: 496 + #ifdef GSPCA_DEBUG 470 497 if (len > USB_BUF_SZ) { 471 498 PDEBUG(D_ERR|D_STREAM, 472 499 "Incorrect variable sequence"); 473 500 return; 474 501 } 502 + #endif 475 503 while (len > 0) { 476 504 if (len < 8) { 477 505 reg_w_buf(gspca_dev, ··· 500 524 501 525 cam = &gspca_dev->cam; 502 526 503 - PDEBUG(D_CONF, "Find Sensor PAC7302"); 504 527 cam->cam_mode = vga_mode; /* only 640x480 */ 505 528 cam->nmodes = ARRAY_SIZE(vga_mode); 506 529 507 - sd->brightness = BRIGHTNESS_DEF; 508 - sd->contrast = CONTRAST_DEF; 509 - sd->colors = COLOR_DEF; 510 - sd->white_balance = WHITEBALANCE_DEF; 511 - sd->red_balance = REDBALANCE_DEF; 512 - sd->blue_balance = BLUEBALANCE_DEF; 513 - sd->gain = GAIN_DEF; 514 - sd->exposure = EXPOSURE_DEF; 515 - sd->autogain = AUTOGAIN_DEF; 516 - sd->hflip = HFLIP_DEF; 517 - sd->vflip = VFLIP_DEF; 530 + gspca_dev->cam.ctrls = sd->ctrls; 531 + 518 532 sd->flags = id->driver_info; 519 533 return 0; 520 534 } ··· 514 548 { 515 549 struct sd *sd = (struct sd *) gspca_dev; 516 550 int i, v; 517 - static const __u8 max[10] = 551 + static const u8 max[10] = 518 552 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, 519 553 0xd4, 0xec}; 520 - static const __u8 delta[10] = 554 + static const u8 delta[10] = 521 555 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, 522 556 0x11, 0x0b}; 523 557 524 558 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 525 559 for (i = 0; i < 10; i++) { 526 560 v = max[i]; 527 - v += (sd->brightness - BRIGHTNESS_MAX) 561 + v += (sd->ctrls[BRIGHTNESS].val - BRIGHTNESS_MAX) 528 562 * 150 / BRIGHTNESS_MAX; /* 200 ? */ 529 - v -= delta[i] * sd->contrast / CONTRAST_MAX; 563 + v -= delta[i] * sd->ctrls[CONTRAST].val / CONTRAST_MAX; 530 564 if (v < 0) 531 565 v = 0; 532 566 else if (v > 0xff) ··· 550 584 reg_w(gspca_dev, 0x11, 0x01); 551 585 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 552 586 for (i = 0; i < 9; i++) { 553 - v = a[i] * sd->colors / COLOR_MAX + b[i]; 587 + v = a[i] * sd->ctrls[COLORS].val / COLOR_MAX + b[i]; 554 588 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); 555 589 reg_w(gspca_dev, 0x0f + 2 * i + 1, v); 556 590 } 557 591 reg_w(gspca_dev, 0xdc, 0x01); 558 - PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); 559 592 } 560 593 561 594 static void setwhitebalance(struct gspca_dev *gspca_dev) ··· 562 597 struct sd *sd = (struct sd *) gspca_dev; 563 598 564 599 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 565 - reg_w(gspca_dev, 0xc6, sd->white_balance); 600 + reg_w(gspca_dev, 0xc6, sd->ctrls[WHITE_BALANCE].val); 566 601 567 602 reg_w(gspca_dev, 0xdc, 0x01); 568 - PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance); 569 603 } 570 604 571 605 static void setredbalance(struct gspca_dev *gspca_dev) ··· 572 608 struct sd *sd = (struct sd *) gspca_dev; 573 609 574 610 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 575 - reg_w(gspca_dev, 0xc5, sd->red_balance); 611 + reg_w(gspca_dev, 0xc5, sd->ctrls[RED_BALANCE].val); 576 612 577 613 reg_w(gspca_dev, 0xdc, 0x01); 578 - PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance); 579 614 } 580 615 581 616 static void setbluebalance(struct gspca_dev *gspca_dev) ··· 582 619 struct sd *sd = (struct sd *) gspca_dev; 583 620 584 621 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 585 - reg_w(gspca_dev, 0xc7, sd->blue_balance); 622 + reg_w(gspca_dev, 0xc7, sd->ctrls[BLUE_BALANCE].val); 586 623 587 624 reg_w(gspca_dev, 0xdc, 0x01); 588 - PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance); 589 625 } 590 626 591 627 static void setgain(struct gspca_dev *gspca_dev) ··· 592 630 struct sd *sd = (struct sd *) gspca_dev; 593 631 594 632 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 595 - reg_w(gspca_dev, 0x10, sd->gain >> 3); 633 + reg_w(gspca_dev, 0x10, sd->ctrls[GAIN].val >> 3); 596 634 597 635 /* load registers to sensor (Bit 0, auto clear) */ 598 636 reg_w(gspca_dev, 0x11, 0x01); ··· 601 639 static void setexposure(struct gspca_dev *gspca_dev) 602 640 { 603 641 struct sd *sd = (struct sd *) gspca_dev; 604 - __u8 clockdiv; 605 - __u16 exposure; 642 + u8 clockdiv; 643 + u16 exposure; 606 644 607 645 /* register 2 of frame 3 contains the clock divider configuring the 608 646 no fps according to the formula: 90 / reg. sd->exposure is the 609 647 desired exposure time in 0.5 ms. */ 610 - clockdiv = (90 * sd->exposure + 1999) / 2000; 648 + clockdiv = (90 * sd->ctrls[EXPOSURE].val + 1999) / 2000; 611 649 612 650 /* Note clockdiv = 3 also works, but when running at 30 fps, depending 613 651 on the scene being recorded, the camera switches to another ··· 626 664 627 665 /* frame exposure time in ms = 1000 * clockdiv / 90 -> 628 666 exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */ 629 - exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv); 667 + exposure = (sd->ctrls[EXPOSURE].val * 45 * 448) / (1000 * clockdiv); 630 668 /* 0 = use full frametime, 448 = no exposure, reverse it */ 631 669 exposure = 448 - exposure; 632 670 ··· 639 677 reg_w(gspca_dev, 0x11, 0x01); 640 678 } 641 679 680 + static void setautogain(struct gspca_dev *gspca_dev) 681 + { 682 + struct sd *sd = (struct sd *) gspca_dev; 683 + 684 + /* when switching to autogain set defaults to make sure 685 + we are on a valid point of the autogain gain / 686 + exposure knee graph, and give this change time to 687 + take effect before doing autogain. */ 688 + if (sd->ctrls[AUTOGAIN].val) { 689 + sd->ctrls[EXPOSURE].val = EXPOSURE_DEF; 690 + sd->ctrls[GAIN].val = GAIN_DEF; 691 + sd->autogain_ignore_frames = 692 + PAC_AUTOGAIN_IGNORE_FRAMES; 693 + } else { 694 + sd->autogain_ignore_frames = -1; 695 + } 696 + setexposure(gspca_dev); 697 + setgain(gspca_dev); 698 + } 699 + 642 700 static void sethvflip(struct gspca_dev *gspca_dev) 643 701 { 644 702 struct sd *sd = (struct sd *) gspca_dev; 645 703 u8 data, hflip, vflip; 646 704 647 - hflip = sd->hflip; 705 + hflip = sd->ctrls[HFLIP].val; 648 706 if (sd->flags & FL_HFLIP) 649 707 hflip = !hflip; 650 - vflip = sd->vflip; 708 + vflip = sd->ctrls[VFLIP].val; 651 709 if (sd->flags & FL_VFLIP) 652 710 vflip = !vflip; 653 711 ··· 690 708 { 691 709 struct sd *sd = (struct sd *) gspca_dev; 692 710 693 - sd->sof_read = 0; 694 - 695 711 reg_w_var(gspca_dev, start_7302, 696 712 page3_7302, sizeof(page3_7302)); 697 713 setbrightcont(gspca_dev); ··· 697 717 setwhitebalance(gspca_dev); 698 718 setredbalance(gspca_dev); 699 719 setbluebalance(gspca_dev); 700 - setgain(gspca_dev); 701 - setexposure(gspca_dev); 720 + setautogain(gspca_dev); 702 721 sethvflip(gspca_dev); 703 722 704 723 /* only resolution 640x480 is supported for pac7302 */ 705 724 706 725 sd->sof_read = 0; 707 - sd->autogain_ignore_frames = 0; 708 - atomic_set(&sd->avg_lum, -1); 726 + atomic_set(&sd->avg_lum, 270 + sd->ctrls[BRIGHTNESS].val); 709 727 710 728 /* start stream */ 711 729 reg_w(gspca_dev, 0xff, 0x01); ··· 729 751 reg_w(gspca_dev, 0x78, 0x40); 730 752 } 731 753 732 - /* Include pac common sof detection functions */ 733 - #include "pac_common.h" 754 + /* !! coarse_grained_expo_autogain is not used !! */ 755 + #define exp_too_low_cnt flags 756 + #define exp_too_high_cnt sof_read 757 + #include "autogain_functions.h" 734 758 735 759 static void do_autogain(struct gspca_dev *gspca_dev) 736 760 { ··· 741 761 int desired_lum; 742 762 const int deadzone = 30; 743 763 744 - if (avg_lum == -1) 764 + if (sd->autogain_ignore_frames < 0) 745 765 return; 746 766 747 - desired_lum = 270 + sd->brightness; 748 - 749 - if (sd->autogain_ignore_frames > 0) 767 + if (sd->autogain_ignore_frames > 0) { 750 768 sd->autogain_ignore_frames--; 751 - else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, 752 - deadzone, GAIN_KNEE, EXPOSURE_KNEE)) 769 + } else { 770 + desired_lum = 270 + sd->ctrls[BRIGHTNESS].val; 771 + 772 + auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, 773 + deadzone, GAIN_KNEE, EXPOSURE_KNEE); 753 774 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 775 + } 754 776 } 755 777 756 - /* JPEG header, part 1 */ 757 - static const unsigned char pac_jpeg_header1[] = { 758 - 0xff, 0xd8, /* SOI: Start of Image */ 778 + /* JPEG header */ 779 + static const u8 jpeg_header[] = { 780 + 0xff, 0xd8, /* SOI: Start of Image */ 759 781 760 - 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ 761 - 0x00, 0x11, /* length = 17 bytes (including this length field) */ 762 - 0x08 /* Precision: 8 */ 763 - /* 2 bytes is placed here: number of image lines */ 764 - /* 2 bytes is placed here: samples per line */ 782 + 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ 783 + 0x00, 0x11, /* length = 17 bytes (including this length field) */ 784 + 0x08, /* Precision: 8 */ 785 + 0x02, 0x80, /* height = 640 (image rotated) */ 786 + 0x01, 0xe0, /* width = 480 */ 787 + 0x03, /* Number of image components: 3 */ 788 + 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ 789 + 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ 790 + 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ 791 + 792 + 0xff, 0xda, /* SOS: Start Of Scan */ 793 + 0x00, 0x0c, /* length = 12 bytes (including this length field) */ 794 + 0x03, /* number of components: 3 */ 795 + 0x01, 0x00, /* selector 1, table 0x00 */ 796 + 0x02, 0x11, /* selector 2, table 0x11 */ 797 + 0x03, 0x11, /* selector 3, table 0x11 */ 798 + 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ 799 + 0x00 /* Successive approximation: 0 */ 765 800 }; 766 - 767 - /* JPEG header, continued */ 768 - static const unsigned char pac_jpeg_header2[] = { 769 - 0x03, /* Number of image components: 3 */ 770 - 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ 771 - 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ 772 - 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ 773 - 774 - 0xff, 0xda, /* SOS: Start Of Scan */ 775 - 0x00, 0x0c, /* length = 12 bytes (including this length field) */ 776 - 0x03, /* number of components: 3 */ 777 - 0x01, 0x00, /* selector 1, table 0x00 */ 778 - 0x02, 0x11, /* selector 2, table 0x11 */ 779 - 0x03, 0x11, /* selector 3, table 0x11 */ 780 - 0x00, 0x3f, /* Spectral selection: 0 .. 63 */ 781 - 0x00 /* Successive approximation: 0 */ 782 - }; 783 - 784 - static void pac_start_frame(struct gspca_dev *gspca_dev, 785 - __u16 lines, __u16 samples_per_line) 786 - { 787 - unsigned char tmpbuf[4]; 788 - 789 - gspca_frame_add(gspca_dev, FIRST_PACKET, 790 - pac_jpeg_header1, sizeof(pac_jpeg_header1)); 791 - 792 - tmpbuf[0] = lines >> 8; 793 - tmpbuf[1] = lines & 0xff; 794 - tmpbuf[2] = samples_per_line >> 8; 795 - tmpbuf[3] = samples_per_line & 0xff; 796 - 797 - gspca_frame_add(gspca_dev, INTER_PACKET, 798 - tmpbuf, sizeof(tmpbuf)); 799 - gspca_frame_add(gspca_dev, INTER_PACKET, 800 - pac_jpeg_header2, sizeof(pac_jpeg_header2)); 801 - } 802 801 803 802 /* this function is run at interrupt level */ 804 803 static void sd_pkt_scan(struct gspca_dev *gspca_dev, ··· 786 827 { 787 828 struct sd *sd = (struct sd *) gspca_dev; 788 829 u8 *image; 789 - unsigned char *sof; 830 + u8 *sof; 790 831 791 832 sof = pac_find_sof(&sd->sof_read, data, len); 792 833 if (sof) { ··· 823 864 n >= lum_offset) 824 865 atomic_set(&sd->avg_lum, data[-lum_offset] + 825 866 data[-lum_offset + 1]); 826 - else 827 - atomic_set(&sd->avg_lum, -1); 828 867 829 868 /* Start the new frame with the jpeg header */ 830 869 /* The PAC7302 has the image rotated 90 degrees */ 831 - pac_start_frame(gspca_dev, 832 - gspca_dev->width, gspca_dev->height); 870 + gspca_frame_add(gspca_dev, FIRST_PACKET, 871 + jpeg_header, sizeof jpeg_header); 833 872 } 834 873 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 835 - } 836 - 837 - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 838 - { 839 - struct sd *sd = (struct sd *) gspca_dev; 840 - 841 - sd->brightness = val; 842 - if (gspca_dev->streaming) 843 - setbrightcont(gspca_dev); 844 - return gspca_dev->usb_err; 845 - } 846 - 847 - static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 848 - { 849 - struct sd *sd = (struct sd *) gspca_dev; 850 - 851 - *val = sd->brightness; 852 - return 0; 853 - } 854 - 855 - static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 856 - { 857 - struct sd *sd = (struct sd *) gspca_dev; 858 - 859 - sd->contrast = val; 860 - if (gspca_dev->streaming) 861 - setbrightcont(gspca_dev); 862 - return gspca_dev->usb_err; 863 - } 864 - 865 - static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 866 - { 867 - struct sd *sd = (struct sd *) gspca_dev; 868 - 869 - *val = sd->contrast; 870 - return 0; 871 - } 872 - 873 - static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) 874 - { 875 - struct sd *sd = (struct sd *) gspca_dev; 876 - 877 - sd->colors = val; 878 - if (gspca_dev->streaming) 879 - setcolors(gspca_dev); 880 - return gspca_dev->usb_err; 881 - } 882 - 883 - static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 884 - { 885 - struct sd *sd = (struct sd *) gspca_dev; 886 - 887 - *val = sd->colors; 888 - return 0; 889 - } 890 - 891 - static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) 892 - { 893 - struct sd *sd = (struct sd *) gspca_dev; 894 - 895 - sd->white_balance = val; 896 - if (gspca_dev->streaming) 897 - setwhitebalance(gspca_dev); 898 - return gspca_dev->usb_err; 899 - } 900 - 901 - static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) 902 - { 903 - struct sd *sd = (struct sd *) gspca_dev; 904 - 905 - *val = sd->white_balance; 906 - return 0; 907 - } 908 - 909 - static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val) 910 - { 911 - struct sd *sd = (struct sd *) gspca_dev; 912 - 913 - sd->red_balance = val; 914 - if (gspca_dev->streaming) 915 - setredbalance(gspca_dev); 916 - return gspca_dev->usb_err; 917 - } 918 - 919 - static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val) 920 - { 921 - struct sd *sd = (struct sd *) gspca_dev; 922 - 923 - *val = sd->red_balance; 924 - return 0; 925 - } 926 - 927 - static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val) 928 - { 929 - struct sd *sd = (struct sd *) gspca_dev; 930 - 931 - sd->blue_balance = val; 932 - if (gspca_dev->streaming) 933 - setbluebalance(gspca_dev); 934 - return gspca_dev->usb_err; 935 - } 936 - 937 - static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val) 938 - { 939 - struct sd *sd = (struct sd *) gspca_dev; 940 - 941 - *val = sd->blue_balance; 942 - return 0; 943 - } 944 - 945 - static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 946 - { 947 - struct sd *sd = (struct sd *) gspca_dev; 948 - 949 - sd->gain = val; 950 - if (gspca_dev->streaming) 951 - setgain(gspca_dev); 952 - return gspca_dev->usb_err; 953 - } 954 - 955 - static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 956 - { 957 - struct sd *sd = (struct sd *) gspca_dev; 958 - 959 - *val = sd->gain; 960 - return 0; 961 - } 962 - 963 - static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) 964 - { 965 - struct sd *sd = (struct sd *) gspca_dev; 966 - 967 - sd->exposure = val; 968 - if (gspca_dev->streaming) 969 - setexposure(gspca_dev); 970 - return gspca_dev->usb_err; 971 - } 972 - 973 - static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 974 - { 975 - struct sd *sd = (struct sd *) gspca_dev; 976 - 977 - *val = sd->exposure; 978 - return 0; 979 - } 980 - 981 - static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 982 - { 983 - struct sd *sd = (struct sd *) gspca_dev; 984 - 985 - sd->autogain = val; 986 - /* when switching to autogain set defaults to make sure 987 - we are on a valid point of the autogain gain / 988 - exposure knee graph, and give this change time to 989 - take effect before doing autogain. */ 990 - if (sd->autogain) { 991 - sd->exposure = EXPOSURE_DEF; 992 - sd->gain = GAIN_DEF; 993 - if (gspca_dev->streaming) { 994 - sd->autogain_ignore_frames = 995 - PAC_AUTOGAIN_IGNORE_FRAMES; 996 - setexposure(gspca_dev); 997 - setgain(gspca_dev); 998 - } 999 - } 1000 - 1001 - return gspca_dev->usb_err; 1002 - } 1003 - 1004 - static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 1005 - { 1006 - struct sd *sd = (struct sd *) gspca_dev; 1007 - 1008 - *val = sd->autogain; 1009 - return 0; 1010 - } 1011 - 1012 - static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) 1013 - { 1014 - struct sd *sd = (struct sd *) gspca_dev; 1015 - 1016 - sd->hflip = val; 1017 - if (gspca_dev->streaming) 1018 - sethvflip(gspca_dev); 1019 - return gspca_dev->usb_err; 1020 - } 1021 - 1022 - static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) 1023 - { 1024 - struct sd *sd = (struct sd *) gspca_dev; 1025 - 1026 - *val = sd->hflip; 1027 - return 0; 1028 - } 1029 - 1030 - static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) 1031 - { 1032 - struct sd *sd = (struct sd *) gspca_dev; 1033 - 1034 - sd->vflip = val; 1035 - if (gspca_dev->streaming) 1036 - sethvflip(gspca_dev); 1037 - return gspca_dev->usb_err; 1038 - } 1039 - 1040 - static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) 1041 - { 1042 - struct sd *sd = (struct sd *) gspca_dev; 1043 - 1044 - *val = sd->vflip; 1045 - return 0; 1046 874 } 1047 875 1048 876 #ifdef CONFIG_VIDEO_ADV_DEBUG 1049 877 static int sd_dbg_s_register(struct gspca_dev *gspca_dev, 1050 878 struct v4l2_dbg_register *reg) 1051 879 { 1052 - __u8 index; 1053 - __u8 value; 880 + u8 index; 881 + u8 value; 1054 882 1055 883 /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit 1056 884 long on the USB bus) ··· 849 1103 ) { 850 1104 /* Currently writing to page 0 is only supported. */ 851 1105 /* reg_w() only supports 8bit index */ 852 - index = reg->reg & 0x000000ff; 853 - value = reg->val & 0x000000ff; 1106 + index = reg->reg; 1107 + value = reg->val; 854 1108 855 1109 /* Note that there shall be no access to other page 856 1110 by any other function between the page swith and ··· 911 1165 912 1166 /* sub-driver description for pac7302 */ 913 1167 static const struct sd_desc sd_desc = { 914 - .name = MODULE_NAME, 1168 + .name = KBUILD_MODNAME, 915 1169 .ctrls = sd_ctrls, 916 1170 .nctrls = ARRAY_SIZE(sd_ctrls), 917 1171 .config = sd_config, ··· 933 1187 /* -- module initialisation -- */ 934 1188 static const struct usb_device_id device_table[] = { 935 1189 {USB_DEVICE(0x06f8, 0x3009)}, 1190 + {USB_DEVICE(0x06f8, 0x301b)}, 936 1191 {USB_DEVICE(0x093a, 0x2620)}, 937 1192 {USB_DEVICE(0x093a, 0x2621)}, 938 1193 {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, ··· 958 1211 } 959 1212 960 1213 static struct usb_driver sd_driver = { 961 - .name = MODULE_NAME, 1214 + .name = KBUILD_MODNAME, 962 1215 .id_table = device_table, 963 1216 .probe = sd_probe, 964 1217 .disconnect = gspca_disconnect,
+503 -635
drivers/media/video/gspca/sn9c20x.c
··· 1 1 /* 2 2 * Sonix sn9c201 sn9c202 library 3 + * 4 + * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr> 3 5 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com> 4 6 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com> 5 7 * ··· 35 33 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); 36 34 MODULE_LICENSE("GPL"); 37 35 38 - #define MODULE_NAME "sn9c20x" 39 - 40 36 /* 41 37 * Pixel format private data 42 38 */ ··· 66 66 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */ 67 67 #define FLIP_DETECT 0x4 68 68 69 + enum e_ctrl { 70 + BRIGHTNESS, 71 + CONTRAST, 72 + SATURATION, 73 + HUE, 74 + GAMMA, 75 + BLUE, 76 + RED, 77 + VFLIP, 78 + HFLIP, 79 + EXPOSURE, 80 + GAIN, 81 + AUTOGAIN, 82 + QUALITY, 83 + NCTRLS /* number of controls */ 84 + }; 85 + 69 86 /* specific webcam descriptor */ 70 87 struct sd { 71 88 struct gspca_dev gspca_dev; 89 + 90 + struct gspca_ctrl ctrls[NCTRLS]; 91 + 92 + struct work_struct work; 93 + struct workqueue_struct *work_thread; 94 + 95 + u32 pktsz; /* (used by pkt_scan) */ 96 + u16 npkt; 97 + s8 nchg; 98 + u8 fmt; /* (used for JPEG QTAB update */ 72 99 73 100 #define MIN_AVG_LUM 80 74 101 #define MAX_AVG_LUM 130 ··· 104 77 u8 older_step; 105 78 u8 exposure_step; 106 79 107 - u8 brightness; 108 - u8 contrast; 109 - u8 saturation; 110 - s16 hue; 111 - u8 gamma; 112 - u8 red; 113 - u8 blue; 114 - 115 - u8 hflip; 116 - u8 vflip; 117 - u8 gain; 118 - u16 exposure; 119 - u8 auto_exposure; 120 - 121 80 u8 i2c_addr; 122 81 u8 sensor; 123 82 u8 hstart; 124 83 u8 vstart; 125 84 126 85 u8 jpeg_hdr[JPEG_HDR_SZ]; 127 - u8 quality; 128 86 129 87 u8 flags; 130 88 }; 89 + 90 + static void qual_upd(struct work_struct *work); 131 91 132 92 struct i2c_reg_u8 { 133 93 u8 reg; ··· 125 111 u8 reg; 126 112 u16 val; 127 113 }; 128 - 129 - static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val); 130 - static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val); 131 - static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val); 132 - static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val); 133 - static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val); 134 - static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val); 135 - static int sd_sethue(struct gspca_dev *gspca_dev, s32 val); 136 - static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val); 137 - static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val); 138 - static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val); 139 - static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val); 140 - static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val); 141 - static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val); 142 - static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val); 143 - static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val); 144 - static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val); 145 - static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val); 146 - static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val); 147 - static int sd_setgain(struct gspca_dev *gspca_dev, s32 val); 148 - static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val); 149 - static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val); 150 - static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val); 151 - static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); 152 - static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); 153 114 154 115 static const struct dmi_system_id flip_dmi_table[] = { 155 116 { ··· 166 177 {} 167 178 }; 168 179 169 - static const struct ctrl sd_ctrls[] = { 170 - { 171 - #define BRIGHTNESS_IDX 0 180 + static void set_cmatrix(struct gspca_dev *gspca_dev); 181 + static void set_gamma(struct gspca_dev *gspca_dev); 182 + static void set_redblue(struct gspca_dev *gspca_dev); 183 + static void set_hvflip(struct gspca_dev *gspca_dev); 184 + static void set_exposure(struct gspca_dev *gspca_dev); 185 + static void set_gain(struct gspca_dev *gspca_dev); 186 + static void set_quality(struct gspca_dev *gspca_dev); 187 + 188 + static const struct ctrl sd_ctrls[NCTRLS] = { 189 + [BRIGHTNESS] = { 172 190 { 173 191 .id = V4L2_CID_BRIGHTNESS, 174 192 .type = V4L2_CTRL_TYPE_INTEGER, ··· 183 187 .minimum = 0, 184 188 .maximum = 0xff, 185 189 .step = 1, 186 - #define BRIGHTNESS_DEFAULT 0x7f 187 - .default_value = BRIGHTNESS_DEFAULT, 190 + .default_value = 0x7f 188 191 }, 189 - .set = sd_setbrightness, 190 - .get = sd_getbrightness, 192 + .set_control = set_cmatrix 191 193 }, 192 - { 193 - #define CONTRAST_IDX 1 194 + [CONTRAST] = { 194 195 { 195 196 .id = V4L2_CID_CONTRAST, 196 197 .type = V4L2_CTRL_TYPE_INTEGER, ··· 195 202 .minimum = 0, 196 203 .maximum = 0xff, 197 204 .step = 1, 198 - #define CONTRAST_DEFAULT 0x7f 199 - .default_value = CONTRAST_DEFAULT, 205 + .default_value = 0x7f 200 206 }, 201 - .set = sd_setcontrast, 202 - .get = sd_getcontrast, 207 + .set_control = set_cmatrix 203 208 }, 204 - { 205 - #define SATURATION_IDX 2 209 + [SATURATION] = { 206 210 { 207 211 .id = V4L2_CID_SATURATION, 208 212 .type = V4L2_CTRL_TYPE_INTEGER, ··· 207 217 .minimum = 0, 208 218 .maximum = 0xff, 209 219 .step = 1, 210 - #define SATURATION_DEFAULT 0x7f 211 - .default_value = SATURATION_DEFAULT, 220 + .default_value = 0x7f 212 221 }, 213 - .set = sd_setsaturation, 214 - .get = sd_getsaturation, 222 + .set_control = set_cmatrix 215 223 }, 216 - { 217 - #define HUE_IDX 3 224 + [HUE] = { 218 225 { 219 226 .id = V4L2_CID_HUE, 220 227 .type = V4L2_CTRL_TYPE_INTEGER, ··· 219 232 .minimum = -180, 220 233 .maximum = 180, 221 234 .step = 1, 222 - #define HUE_DEFAULT 0 223 - .default_value = HUE_DEFAULT, 235 + .default_value = 0 224 236 }, 225 - .set = sd_sethue, 226 - .get = sd_gethue, 237 + .set_control = set_cmatrix 227 238 }, 228 - { 229 - #define GAMMA_IDX 4 239 + [GAMMA] = { 230 240 { 231 241 .id = V4L2_CID_GAMMA, 232 242 .type = V4L2_CTRL_TYPE_INTEGER, ··· 231 247 .minimum = 0, 232 248 .maximum = 0xff, 233 249 .step = 1, 234 - #define GAMMA_DEFAULT 0x10 235 - .default_value = GAMMA_DEFAULT, 250 + .default_value = 0x10 236 251 }, 237 - .set = sd_setgamma, 238 - .get = sd_getgamma, 252 + .set_control = set_gamma 239 253 }, 240 - { 241 - #define BLUE_IDX 5 254 + [BLUE] = { 242 255 { 243 256 .id = V4L2_CID_BLUE_BALANCE, 244 257 .type = V4L2_CTRL_TYPE_INTEGER, ··· 243 262 .minimum = 0, 244 263 .maximum = 0x7f, 245 264 .step = 1, 246 - #define BLUE_DEFAULT 0x28 247 - .default_value = BLUE_DEFAULT, 265 + .default_value = 0x28 248 266 }, 249 - .set = sd_setbluebalance, 250 - .get = sd_getbluebalance, 267 + .set_control = set_redblue 251 268 }, 252 - { 253 - #define RED_IDX 6 269 + [RED] = { 254 270 { 255 271 .id = V4L2_CID_RED_BALANCE, 256 272 .type = V4L2_CTRL_TYPE_INTEGER, ··· 255 277 .minimum = 0, 256 278 .maximum = 0x7f, 257 279 .step = 1, 258 - #define RED_DEFAULT 0x28 259 - .default_value = RED_DEFAULT, 280 + .default_value = 0x28 260 281 }, 261 - .set = sd_setredbalance, 262 - .get = sd_getredbalance, 282 + .set_control = set_redblue 263 283 }, 264 - { 265 - #define HFLIP_IDX 7 284 + [HFLIP] = { 266 285 { 267 286 .id = V4L2_CID_HFLIP, 268 287 .type = V4L2_CTRL_TYPE_BOOLEAN, ··· 267 292 .minimum = 0, 268 293 .maximum = 1, 269 294 .step = 1, 270 - #define HFLIP_DEFAULT 0 271 - .default_value = HFLIP_DEFAULT, 295 + .default_value = 0, 272 296 }, 273 - .set = sd_sethflip, 274 - .get = sd_gethflip, 297 + .set_control = set_hvflip 275 298 }, 276 - { 277 - #define VFLIP_IDX 8 299 + [VFLIP] = { 278 300 { 279 301 .id = V4L2_CID_VFLIP, 280 302 .type = V4L2_CTRL_TYPE_BOOLEAN, ··· 279 307 .minimum = 0, 280 308 .maximum = 1, 281 309 .step = 1, 282 - #define VFLIP_DEFAULT 0 283 - .default_value = VFLIP_DEFAULT, 310 + .default_value = 0, 284 311 }, 285 - .set = sd_setvflip, 286 - .get = sd_getvflip, 312 + .set_control = set_hvflip 287 313 }, 288 - { 289 - #define EXPOSURE_IDX 9 314 + [EXPOSURE] = { 290 315 { 291 316 .id = V4L2_CID_EXPOSURE, 292 317 .type = V4L2_CTRL_TYPE_INTEGER, ··· 291 322 .minimum = 0, 292 323 .maximum = 0x1780, 293 324 .step = 1, 294 - #define EXPOSURE_DEFAULT 0x33 295 - .default_value = EXPOSURE_DEFAULT, 325 + .default_value = 0x33, 296 326 }, 297 - .set = sd_setexposure, 298 - .get = sd_getexposure, 327 + .set_control = set_exposure 299 328 }, 300 - { 301 - #define GAIN_IDX 10 329 + [GAIN] = { 302 330 { 303 331 .id = V4L2_CID_GAIN, 304 332 .type = V4L2_CTRL_TYPE_INTEGER, ··· 303 337 .minimum = 0, 304 338 .maximum = 28, 305 339 .step = 1, 306 - #define GAIN_DEFAULT 0x00 307 - .default_value = GAIN_DEFAULT, 340 + .default_value = 0, 308 341 }, 309 - .set = sd_setgain, 310 - .get = sd_getgain, 342 + .set_control = set_gain 311 343 }, 312 - { 313 - #define AUTOGAIN_IDX 11 344 + [AUTOGAIN] = { 314 345 { 315 346 .id = V4L2_CID_AUTOGAIN, 316 347 .type = V4L2_CTRL_TYPE_BOOLEAN, ··· 315 352 .minimum = 0, 316 353 .maximum = 1, 317 354 .step = 1, 318 - #define AUTO_EXPOSURE_DEFAULT 1 319 - .default_value = AUTO_EXPOSURE_DEFAULT, 355 + .default_value = 1, 320 356 }, 321 - .set = sd_setautoexposure, 322 - .get = sd_getautoexposure, 357 + }, 358 + [QUALITY] = { 359 + { 360 + .id = V4L2_CID_JPEG_COMPRESSION_QUALITY, 361 + .type = V4L2_CTRL_TYPE_INTEGER, 362 + .name = "Compression Quality", 363 + #define QUALITY_MIN 50 364 + #define QUALITY_MAX 90 365 + #define QUALITY_DEF 80 366 + .minimum = QUALITY_MIN, 367 + .maximum = QUALITY_MAX, 368 + .step = 1, 369 + .default_value = QUALITY_DEF, 370 + }, 371 + .set_control = set_quality 323 372 }, 324 373 }; 325 374 ··· 851 876 }; 852 877 853 878 static struct i2c_reg_u8 soi968_init[] = { 854 - {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f}, 879 + {0x0c, 0x00}, {0x0f, 0x1f}, 855 880 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, 856 881 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, 857 882 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, ··· 877 902 }; 878 903 879 904 static struct i2c_reg_u8 ov7670_init[] = { 880 - {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, 905 + {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, 881 906 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, 882 907 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, 883 908 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00}, ··· 934 959 }; 935 960 936 961 static struct i2c_reg_u8 ov9650_init[] = { 937 - {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78}, 962 + {0x00, 0x00}, {0x01, 0x78}, 938 963 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, 939 964 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, 940 965 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00}, ··· 964 989 }; 965 990 966 991 static struct i2c_reg_u8 ov9655_init[] = { 967 - {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba}, 992 + {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba}, 968 993 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08}, 969 994 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d}, 970 995 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57}, ··· 1087 1112 {0x23, 0x09}, {0x01, 0x08}, 1088 1113 }; 1089 1114 1090 - static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) 1115 + static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) 1091 1116 { 1092 1117 struct usb_device *dev = gspca_dev->dev; 1093 1118 int result; 1119 + 1120 + if (gspca_dev->usb_err < 0) 1121 + return; 1094 1122 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 1095 1123 0x00, 1096 1124 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, ··· 1103 1125 length, 1104 1126 500); 1105 1127 if (unlikely(result < 0 || result != length)) { 1106 - pr_err("Read register failed 0x%02X\n", reg); 1107 - return -EIO; 1128 + pr_err("Read register %02x failed %d\n", reg, result); 1129 + gspca_dev->usb_err = result; 1108 1130 } 1109 - return 0; 1110 1131 } 1111 1132 1112 - static int reg_w(struct gspca_dev *gspca_dev, u16 reg, 1133 + static void reg_w(struct gspca_dev *gspca_dev, u16 reg, 1113 1134 const u8 *buffer, int length) 1114 1135 { 1115 1136 struct usb_device *dev = gspca_dev->dev; 1116 1137 int result; 1138 + 1139 + if (gspca_dev->usb_err < 0) 1140 + return; 1117 1141 memcpy(gspca_dev->usb_buf, buffer, length); 1118 1142 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1119 1143 0x08, ··· 1126 1146 length, 1127 1147 500); 1128 1148 if (unlikely(result < 0 || result != length)) { 1129 - pr_err("Write register failed index 0x%02X\n", reg); 1130 - return -EIO; 1149 + pr_err("Write register %02x failed %d\n", reg, result); 1150 + gspca_dev->usb_err = result; 1131 1151 } 1132 - return 0; 1133 1152 } 1134 1153 1135 - static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) 1154 + static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) 1136 1155 { 1137 - u8 data[1] = {value}; 1138 - return reg_w(gspca_dev, reg, data, 1); 1156 + reg_w(gspca_dev, reg, &value, 1); 1139 1157 } 1140 1158 1141 - static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) 1159 + static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) 1142 1160 { 1143 1161 int i; 1162 + 1144 1163 reg_w(gspca_dev, 0x10c0, buffer, 8); 1145 1164 for (i = 0; i < 5; i++) { 1146 1165 reg_r(gspca_dev, 0x10c0, 1); 1166 + if (gspca_dev->usb_err < 0) 1167 + return; 1147 1168 if (gspca_dev->usb_buf[0] & 0x04) { 1148 - if (gspca_dev->usb_buf[0] & 0x08) 1149 - return -EIO; 1150 - return 0; 1169 + if (gspca_dev->usb_buf[0] & 0x08) { 1170 + pr_err("i2c_w error\n"); 1171 + gspca_dev->usb_err = -EIO; 1172 + } 1173 + return; 1151 1174 } 1152 - msleep(1); 1175 + msleep(10); 1153 1176 } 1154 - return -EIO; 1177 + pr_err("i2c_w reg %02x no response\n", buffer[2]); 1178 + /* gspca_dev->usb_err = -EIO; fixme: may occur */ 1155 1179 } 1156 1180 1157 - static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) 1181 + static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) 1158 1182 { 1159 1183 struct sd *sd = (struct sd *) gspca_dev; 1160 - 1161 1184 u8 row[8]; 1162 1185 1163 1186 /* ··· 1176 1193 row[6] = 0x00; 1177 1194 row[7] = 0x10; 1178 1195 1179 - return i2c_w(gspca_dev, row); 1196 + i2c_w(gspca_dev, row); 1180 1197 } 1181 1198 1182 - static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) 1199 + static void i2c_w1_buf(struct gspca_dev *gspca_dev, 1200 + struct i2c_reg_u8 *buf, int sz) 1201 + { 1202 + while (--sz >= 0) { 1203 + i2c_w1(gspca_dev, buf->reg, buf->val); 1204 + buf++; 1205 + } 1206 + } 1207 + 1208 + static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) 1183 1209 { 1184 1210 struct sd *sd = (struct sd *) gspca_dev; 1185 1211 u8 row[8]; ··· 1200 1208 row[0] = 0x81 | (3 << 4); 1201 1209 row[1] = sd->i2c_addr; 1202 1210 row[2] = reg; 1203 - row[3] = (val >> 8) & 0xff; 1204 - row[4] = val & 0xff; 1211 + row[3] = val >> 8; 1212 + row[4] = val; 1205 1213 row[5] = 0x00; 1206 1214 row[6] = 0x00; 1207 1215 row[7] = 0x10; 1208 1216 1209 - return i2c_w(gspca_dev, row); 1217 + i2c_w(gspca_dev, row); 1210 1218 } 1211 1219 1212 - static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) 1220 + static void i2c_w2_buf(struct gspca_dev *gspca_dev, 1221 + struct i2c_reg_u16 *buf, int sz) 1222 + { 1223 + while (--sz >= 0) { 1224 + i2c_w2(gspca_dev, buf->reg, buf->val); 1225 + buf++; 1226 + } 1227 + } 1228 + 1229 + static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) 1213 1230 { 1214 1231 struct sd *sd = (struct sd *) gspca_dev; 1215 1232 u8 row[8]; ··· 1231 1230 row[5] = 0; 1232 1231 row[6] = 0; 1233 1232 row[7] = 0x10; 1234 - if (i2c_w(gspca_dev, row) < 0) 1235 - return -EIO; 1233 + i2c_w(gspca_dev, row); 1236 1234 row[0] = 0x81 | (1 << 4) | 0x02; 1237 1235 row[2] = 0; 1238 - if (i2c_w(gspca_dev, row) < 0) 1239 - return -EIO; 1240 - if (reg_r(gspca_dev, 0x10c2, 5) < 0) 1241 - return -EIO; 1236 + i2c_w(gspca_dev, row); 1237 + reg_r(gspca_dev, 0x10c2, 5); 1242 1238 *val = gspca_dev->usb_buf[4]; 1243 - return 0; 1244 1239 } 1245 1240 1246 - static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) 1241 + static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) 1247 1242 { 1248 1243 struct sd *sd = (struct sd *) gspca_dev; 1249 1244 u8 row[8]; ··· 1252 1255 row[5] = 0; 1253 1256 row[6] = 0; 1254 1257 row[7] = 0x10; 1255 - if (i2c_w(gspca_dev, row) < 0) 1256 - return -EIO; 1258 + i2c_w(gspca_dev, row); 1257 1259 row[0] = 0x81 | (2 << 4) | 0x02; 1258 1260 row[2] = 0; 1259 - if (i2c_w(gspca_dev, row) < 0) 1260 - return -EIO; 1261 - if (reg_r(gspca_dev, 0x10c2, 5) < 0) 1262 - return -EIO; 1261 + i2c_w(gspca_dev, row); 1262 + reg_r(gspca_dev, 0x10c2, 5); 1263 1263 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; 1264 - return 0; 1265 1264 } 1266 1265 1267 - static int ov9650_init_sensor(struct gspca_dev *gspca_dev) 1266 + static void ov9650_init_sensor(struct gspca_dev *gspca_dev) 1268 1267 { 1269 - int i; 1270 1268 u16 id; 1271 1269 struct sd *sd = (struct sd *) gspca_dev; 1272 1270 1273 - if (i2c_r2(gspca_dev, 0x1c, &id) < 0) 1274 - return -EINVAL; 1271 + i2c_r2(gspca_dev, 0x1c, &id); 1272 + if (gspca_dev->usb_err < 0) 1273 + return; 1275 1274 1276 1275 if (id != 0x7fa2) { 1277 1276 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id); 1278 - return -ENODEV; 1277 + gspca_dev->usb_err = -ENODEV; 1278 + return; 1279 1279 } 1280 1280 1281 - for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) { 1282 - if (i2c_w1(gspca_dev, ov9650_init[i].reg, 1283 - ov9650_init[i].val) < 0) { 1284 - pr_err("OV9650 sensor initialization failed\n"); 1285 - return -ENODEV; 1286 - } 1287 - } 1281 + i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1282 + msleep(200); 1283 + i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init)); 1284 + if (gspca_dev->usb_err < 0) 1285 + pr_err("OV9650 sensor initialization failed\n"); 1288 1286 sd->hstart = 1; 1289 1287 sd->vstart = 7; 1290 - return 0; 1291 1288 } 1292 1289 1293 - static int ov9655_init_sensor(struct gspca_dev *gspca_dev) 1290 + static void ov9655_init_sensor(struct gspca_dev *gspca_dev) 1294 1291 { 1295 - int i; 1296 1292 struct sd *sd = (struct sd *) gspca_dev; 1297 1293 1298 - for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) { 1299 - if (i2c_w1(gspca_dev, ov9655_init[i].reg, 1300 - ov9655_init[i].val) < 0) { 1301 - pr_err("OV9655 sensor initialization failed\n"); 1302 - return -ENODEV; 1303 - } 1304 - } 1294 + i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1295 + msleep(200); 1296 + i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init)); 1297 + if (gspca_dev->usb_err < 0) 1298 + pr_err("OV9655 sensor initialization failed\n"); 1299 + 1305 1300 /* disable hflip and vflip */ 1306 - gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1301 + gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP); 1307 1302 sd->hstart = 1; 1308 1303 sd->vstart = 2; 1309 - return 0; 1310 1304 } 1311 1305 1312 - static int soi968_init_sensor(struct gspca_dev *gspca_dev) 1306 + static void soi968_init_sensor(struct gspca_dev *gspca_dev) 1313 1307 { 1314 - int i; 1315 1308 struct sd *sd = (struct sd *) gspca_dev; 1316 1309 1317 - for (i = 0; i < ARRAY_SIZE(soi968_init); i++) { 1318 - if (i2c_w1(gspca_dev, soi968_init[i].reg, 1319 - soi968_init[i].val) < 0) { 1320 - pr_err("SOI968 sensor initialization failed\n"); 1321 - return -ENODEV; 1322 - } 1323 - } 1310 + i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1311 + msleep(200); 1312 + i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init)); 1313 + if (gspca_dev->usb_err < 0) 1314 + pr_err("SOI968 sensor initialization failed\n"); 1315 + 1324 1316 /* disable hflip and vflip */ 1325 - gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) 1326 - | (1 << EXPOSURE_IDX); 1317 + gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP) 1318 + | (1 << EXPOSURE); 1327 1319 sd->hstart = 60; 1328 1320 sd->vstart = 11; 1329 - return 0; 1330 1321 } 1331 1322 1332 - static int ov7660_init_sensor(struct gspca_dev *gspca_dev) 1323 + static void ov7660_init_sensor(struct gspca_dev *gspca_dev) 1333 1324 { 1334 - int i; 1335 1325 struct sd *sd = (struct sd *) gspca_dev; 1336 1326 1337 - for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) { 1338 - if (i2c_w1(gspca_dev, ov7660_init[i].reg, 1339 - ov7660_init[i].val) < 0) { 1340 - pr_err("OV7660 sensor initialization failed\n"); 1341 - return -ENODEV; 1342 - } 1343 - } 1327 + i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1328 + msleep(200); 1329 + i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init)); 1330 + if (gspca_dev->usb_err < 0) 1331 + pr_err("OV7660 sensor initialization failed\n"); 1344 1332 sd->hstart = 3; 1345 1333 sd->vstart = 3; 1346 - return 0; 1347 1334 } 1348 1335 1349 - static int ov7670_init_sensor(struct gspca_dev *gspca_dev) 1336 + static void ov7670_init_sensor(struct gspca_dev *gspca_dev) 1350 1337 { 1351 - int i; 1352 1338 struct sd *sd = (struct sd *) gspca_dev; 1353 1339 1354 - for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) { 1355 - if (i2c_w1(gspca_dev, ov7670_init[i].reg, 1356 - ov7670_init[i].val) < 0) { 1357 - pr_err("OV7670 sensor initialization failed\n"); 1358 - return -ENODEV; 1359 - } 1360 - } 1340 + i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1341 + msleep(200); 1342 + i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init)); 1343 + if (gspca_dev->usb_err < 0) 1344 + pr_err("OV7670 sensor initialization failed\n"); 1345 + 1361 1346 /* disable hflip and vflip */ 1362 - gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1347 + gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP); 1363 1348 sd->hstart = 0; 1364 1349 sd->vstart = 1; 1365 - return 0; 1366 1350 } 1367 1351 1368 - static int mt9v_init_sensor(struct gspca_dev *gspca_dev) 1352 + static void mt9v_init_sensor(struct gspca_dev *gspca_dev) 1369 1353 { 1370 1354 struct sd *sd = (struct sd *) gspca_dev; 1371 - int i; 1372 1355 u16 value; 1373 - int ret; 1374 1356 1375 1357 sd->i2c_addr = 0x5d; 1376 - ret = i2c_r2(gspca_dev, 0xff, &value); 1377 - if ((ret == 0) && (value == 0x8243)) { 1378 - for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) { 1379 - if (i2c_w2(gspca_dev, mt9v011_init[i].reg, 1380 - mt9v011_init[i].val) < 0) { 1381 - pr_err("MT9V011 sensor initialization failed\n"); 1382 - return -ENODEV; 1383 - } 1358 + i2c_r2(gspca_dev, 0xff, &value); 1359 + if (gspca_dev->usb_err >= 0 1360 + && value == 0x8243) { 1361 + i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init)); 1362 + if (gspca_dev->usb_err < 0) { 1363 + pr_err("MT9V011 sensor initialization failed\n"); 1364 + return; 1384 1365 } 1385 1366 sd->hstart = 2; 1386 1367 sd->vstart = 2; 1387 1368 sd->sensor = SENSOR_MT9V011; 1388 1369 pr_info("MT9V011 sensor detected\n"); 1389 - return 0; 1370 + return; 1390 1371 } 1391 1372 1373 + gspca_dev->usb_err = 0; 1392 1374 sd->i2c_addr = 0x5c; 1393 1375 i2c_w2(gspca_dev, 0x01, 0x0004); 1394 - ret = i2c_r2(gspca_dev, 0xff, &value); 1395 - if ((ret == 0) && (value == 0x823a)) { 1396 - for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) { 1397 - if (i2c_w2(gspca_dev, mt9v111_init[i].reg, 1398 - mt9v111_init[i].val) < 0) { 1399 - pr_err("MT9V111 sensor initialization failed\n"); 1400 - return -ENODEV; 1401 - } 1376 + i2c_r2(gspca_dev, 0xff, &value); 1377 + if (gspca_dev->usb_err >= 0 1378 + && value == 0x823a) { 1379 + i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init)); 1380 + if (gspca_dev->usb_err < 0) { 1381 + pr_err("MT9V111 sensor initialization failed\n"); 1382 + return; 1402 1383 } 1403 - gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) 1404 - | (1 << AUTOGAIN_IDX) 1405 - | (1 << GAIN_IDX); 1384 + gspca_dev->ctrl_dis = (1 << EXPOSURE) 1385 + | (1 << AUTOGAIN) 1386 + | (1 << GAIN); 1406 1387 sd->hstart = 2; 1407 1388 sd->vstart = 2; 1408 1389 sd->sensor = SENSOR_MT9V111; 1409 1390 pr_info("MT9V111 sensor detected\n"); 1410 - return 0; 1391 + return; 1411 1392 } 1412 1393 1394 + gspca_dev->usb_err = 0; 1413 1395 sd->i2c_addr = 0x5d; 1414 - ret = i2c_w2(gspca_dev, 0xf0, 0x0000); 1415 - if (ret < 0) { 1396 + i2c_w2(gspca_dev, 0xf0, 0x0000); 1397 + if (gspca_dev->usb_err < 0) { 1398 + gspca_dev->usb_err = 0; 1416 1399 sd->i2c_addr = 0x48; 1417 1400 i2c_w2(gspca_dev, 0xf0, 0x0000); 1418 1401 } 1419 - ret = i2c_r2(gspca_dev, 0x00, &value); 1420 - if ((ret == 0) && (value == 0x1229)) { 1421 - for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) { 1422 - if (i2c_w2(gspca_dev, mt9v112_init[i].reg, 1423 - mt9v112_init[i].val) < 0) { 1424 - pr_err("MT9V112 sensor initialization failed\n"); 1425 - return -ENODEV; 1426 - } 1402 + i2c_r2(gspca_dev, 0x00, &value); 1403 + if (gspca_dev->usb_err >= 0 1404 + && value == 0x1229) { 1405 + i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init)); 1406 + if (gspca_dev->usb_err < 0) { 1407 + pr_err("MT9V112 sensor initialization failed\n"); 1408 + return; 1427 1409 } 1428 1410 sd->hstart = 6; 1429 1411 sd->vstart = 2; 1430 1412 sd->sensor = SENSOR_MT9V112; 1431 1413 pr_info("MT9V112 sensor detected\n"); 1432 - return 0; 1414 + return; 1433 1415 } 1434 1416 1435 - return -ENODEV; 1417 + gspca_dev->usb_err = -ENODEV; 1436 1418 } 1437 1419 1438 - static int mt9m112_init_sensor(struct gspca_dev *gspca_dev) 1420 + static void mt9m112_init_sensor(struct gspca_dev *gspca_dev) 1439 1421 { 1440 1422 struct sd *sd = (struct sd *) gspca_dev; 1441 - int i; 1442 - for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) { 1443 - if (i2c_w2(gspca_dev, mt9m112_init[i].reg, 1444 - mt9m112_init[i].val) < 0) { 1445 - pr_err("MT9M112 sensor initialization failed\n"); 1446 - return -ENODEV; 1447 - } 1448 - } 1449 - gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) 1450 - | (1 << GAIN_IDX); 1423 + 1424 + i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init)); 1425 + if (gspca_dev->usb_err < 0) 1426 + pr_err("MT9M112 sensor initialization failed\n"); 1427 + 1428 + gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN) 1429 + | (1 << GAIN); 1451 1430 sd->hstart = 0; 1452 1431 sd->vstart = 2; 1453 - return 0; 1454 1432 } 1455 1433 1456 - static int mt9m111_init_sensor(struct gspca_dev *gspca_dev) 1434 + static void mt9m111_init_sensor(struct gspca_dev *gspca_dev) 1457 1435 { 1458 1436 struct sd *sd = (struct sd *) gspca_dev; 1459 - int i; 1460 - for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) { 1461 - if (i2c_w2(gspca_dev, mt9m111_init[i].reg, 1462 - mt9m111_init[i].val) < 0) { 1463 - pr_err("MT9M111 sensor initialization failed\n"); 1464 - return -ENODEV; 1465 - } 1466 - } 1467 - gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) 1468 - | (1 << GAIN_IDX); 1437 + 1438 + i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init)); 1439 + if (gspca_dev->usb_err < 0) 1440 + pr_err("MT9M111 sensor initialization failed\n"); 1441 + 1442 + gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN) 1443 + | (1 << GAIN); 1469 1444 sd->hstart = 0; 1470 1445 sd->vstart = 2; 1471 - return 0; 1472 1446 } 1473 1447 1474 - static int mt9m001_init_sensor(struct gspca_dev *gspca_dev) 1448 + static void mt9m001_init_sensor(struct gspca_dev *gspca_dev) 1475 1449 { 1476 1450 struct sd *sd = (struct sd *) gspca_dev; 1477 - int i; 1478 1451 u16 id; 1479 1452 1480 - if (i2c_r2(gspca_dev, 0x00, &id) < 0) 1481 - return -EINVAL; 1453 + i2c_r2(gspca_dev, 0x00, &id); 1454 + if (gspca_dev->usb_err < 0) 1455 + return; 1482 1456 1483 1457 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ 1484 1458 switch (id) { ··· 1462 1494 break; 1463 1495 default: 1464 1496 pr_err("No MT9M001 chip detected, ID = %x\n\n", id); 1465 - return -ENODEV; 1497 + gspca_dev->usb_err = -ENODEV; 1498 + return; 1466 1499 } 1467 1500 1468 - for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) { 1469 - if (i2c_w2(gspca_dev, mt9m001_init[i].reg, 1470 - mt9m001_init[i].val) < 0) { 1471 - pr_err("MT9M001 sensor initialization failed\n"); 1472 - return -ENODEV; 1473 - } 1474 - } 1501 + i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init)); 1502 + if (gspca_dev->usb_err < 0) 1503 + pr_err("MT9M001 sensor initialization failed\n"); 1504 + 1475 1505 /* disable hflip and vflip */ 1476 - gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1506 + gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP); 1477 1507 sd->hstart = 1; 1478 1508 sd->vstart = 1; 1479 - return 0; 1480 1509 } 1481 1510 1482 - static int hv7131r_init_sensor(struct gspca_dev *gspca_dev) 1511 + static void hv7131r_init_sensor(struct gspca_dev *gspca_dev) 1483 1512 { 1484 - int i; 1485 1513 struct sd *sd = (struct sd *) gspca_dev; 1486 1514 1487 - for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) { 1488 - if (i2c_w1(gspca_dev, hv7131r_init[i].reg, 1489 - hv7131r_init[i].val) < 0) { 1490 - pr_err("HV7131R Sensor initialization failed\n"); 1491 - return -ENODEV; 1492 - } 1493 - } 1515 + i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init)); 1516 + if (gspca_dev->usb_err < 0) 1517 + pr_err("HV7131R Sensor initialization failed\n"); 1518 + 1494 1519 sd->hstart = 0; 1495 1520 sd->vstart = 1; 1496 - return 0; 1497 1521 } 1498 1522 1499 - static int set_cmatrix(struct gspca_dev *gspca_dev) 1523 + static void set_cmatrix(struct gspca_dev *gspca_dev) 1500 1524 { 1501 1525 struct sd *sd = (struct sd *) gspca_dev; 1502 - s32 hue_coord, hue_index = 180 + sd->hue; 1526 + int satur; 1527 + s32 hue_coord, hue_index = 180 + sd->ctrls[HUE].val; 1503 1528 u8 cmatrix[21]; 1504 1529 1505 1530 memset(cmatrix, 0, sizeof cmatrix); 1506 - cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26; 1531 + cmatrix[2] = (sd->ctrls[CONTRAST].val * 0x25 / 0x100) + 0x26; 1507 1532 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; 1508 1533 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; 1509 - cmatrix[18] = sd->brightness - 0x80; 1534 + cmatrix[18] = sd->ctrls[BRIGHTNESS].val - 0x80; 1510 1535 1511 - hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8; 1536 + satur = sd->ctrls[SATURATION].val; 1537 + hue_coord = (hsv_red_x[hue_index] * satur) >> 8; 1512 1538 cmatrix[6] = hue_coord; 1513 1539 cmatrix[7] = (hue_coord >> 8) & 0x0f; 1514 1540 1515 - hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8; 1541 + hue_coord = (hsv_red_y[hue_index] * satur) >> 8; 1516 1542 cmatrix[8] = hue_coord; 1517 1543 cmatrix[9] = (hue_coord >> 8) & 0x0f; 1518 1544 1519 - hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8; 1545 + hue_coord = (hsv_green_x[hue_index] * satur) >> 8; 1520 1546 cmatrix[10] = hue_coord; 1521 1547 cmatrix[11] = (hue_coord >> 8) & 0x0f; 1522 1548 1523 - hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8; 1549 + hue_coord = (hsv_green_y[hue_index] * satur) >> 8; 1524 1550 cmatrix[12] = hue_coord; 1525 1551 cmatrix[13] = (hue_coord >> 8) & 0x0f; 1526 1552 1527 - hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8; 1553 + hue_coord = (hsv_blue_x[hue_index] * satur) >> 8; 1528 1554 cmatrix[14] = hue_coord; 1529 1555 cmatrix[15] = (hue_coord >> 8) & 0x0f; 1530 1556 1531 - hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8; 1557 + hue_coord = (hsv_blue_y[hue_index] * satur) >> 8; 1532 1558 cmatrix[16] = hue_coord; 1533 1559 cmatrix[17] = (hue_coord >> 8) & 0x0f; 1534 1560 1535 - return reg_w(gspca_dev, 0x10e1, cmatrix, 21); 1561 + reg_w(gspca_dev, 0x10e1, cmatrix, 21); 1536 1562 } 1537 1563 1538 - static int set_gamma(struct gspca_dev *gspca_dev) 1564 + static void set_gamma(struct gspca_dev *gspca_dev) 1539 1565 { 1540 1566 struct sd *sd = (struct sd *) gspca_dev; 1541 1567 u8 gamma[17]; 1542 - u8 gval = sd->gamma * 0xb8 / 0x100; 1543 - 1568 + u8 gval = sd->ctrls[GAMMA].val * 0xb8 / 0x100; 1544 1569 1545 1570 gamma[0] = 0x0a; 1546 1571 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); ··· 1553 1592 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8); 1554 1593 gamma[16] = 0xf5; 1555 1594 1556 - return reg_w(gspca_dev, 0x1190, gamma, 17); 1595 + reg_w(gspca_dev, 0x1190, gamma, 17); 1557 1596 } 1558 1597 1559 - static int set_redblue(struct gspca_dev *gspca_dev) 1598 + static void set_redblue(struct gspca_dev *gspca_dev) 1560 1599 { 1561 1600 struct sd *sd = (struct sd *) gspca_dev; 1562 - reg_w1(gspca_dev, 0x118c, sd->red); 1563 - reg_w1(gspca_dev, 0x118f, sd->blue); 1564 - return 0; 1601 + 1602 + reg_w1(gspca_dev, 0x118c, sd->ctrls[RED].val); 1603 + reg_w1(gspca_dev, 0x118f, sd->ctrls[BLUE].val); 1565 1604 } 1566 1605 1567 - static int set_hvflip(struct gspca_dev *gspca_dev) 1606 + static void set_hvflip(struct gspca_dev *gspca_dev) 1568 1607 { 1569 1608 u8 value, tslb, hflip, vflip; 1570 1609 u16 value2; 1571 1610 struct sd *sd = (struct sd *) gspca_dev; 1572 1611 1573 1612 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) { 1574 - hflip = !sd->hflip; 1575 - vflip = !sd->vflip; 1613 + hflip = !sd->ctrls[HFLIP].val; 1614 + vflip = !sd->ctrls[VFLIP].val; 1576 1615 } else { 1577 - hflip = sd->hflip; 1578 - vflip = sd->vflip; 1616 + hflip = sd->ctrls[HFLIP].val; 1617 + vflip = sd->ctrls[VFLIP].val; 1579 1618 } 1580 1619 1581 1620 switch (sd->sensor) { ··· 1586 1625 if (vflip) { 1587 1626 value |= 0x10; 1588 1627 sd->vstart = 2; 1589 - } else 1628 + } else { 1590 1629 sd->vstart = 3; 1630 + } 1591 1631 reg_w1(gspca_dev, 0x1182, sd->vstart); 1592 1632 i2c_w1(gspca_dev, 0x1e, value); 1593 1633 break; ··· 1636 1674 i2c_w1(gspca_dev, 0x01, value); 1637 1675 break; 1638 1676 } 1639 - return 0; 1640 1677 } 1641 1678 1642 - static int set_exposure(struct gspca_dev *gspca_dev) 1679 + static void set_exposure(struct gspca_dev *gspca_dev) 1643 1680 { 1644 1681 struct sd *sd = (struct sd *) gspca_dev; 1645 1682 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e}; 1683 + int expo; 1684 + 1685 + expo = sd->ctrls[EXPOSURE].val; 1646 1686 switch (sd->sensor) { 1647 1687 case SENSOR_OV7660: 1648 1688 case SENSOR_OV7670: ··· 1652 1688 case SENSOR_OV9650: 1653 1689 exp[0] |= (3 << 4); 1654 1690 exp[2] = 0x2d; 1655 - exp[3] = sd->exposure & 0xff; 1656 - exp[4] = sd->exposure >> 8; 1691 + exp[3] = expo; 1692 + exp[4] = expo >> 8; 1657 1693 break; 1658 1694 case SENSOR_MT9M001: 1659 1695 case SENSOR_MT9V112: 1660 1696 case SENSOR_MT9V011: 1661 1697 exp[0] |= (3 << 4); 1662 1698 exp[2] = 0x09; 1663 - exp[3] = sd->exposure >> 8; 1664 - exp[4] = sd->exposure & 0xff; 1699 + exp[3] = expo >> 8; 1700 + exp[4] = expo; 1665 1701 break; 1666 1702 case SENSOR_HV7131R: 1667 1703 exp[0] |= (4 << 4); 1668 1704 exp[2] = 0x25; 1669 - exp[3] = (sd->exposure >> 5) & 0xff; 1670 - exp[4] = (sd->exposure << 3) & 0xff; 1705 + exp[3] = expo >> 5; 1706 + exp[4] = expo << 3; 1671 1707 exp[5] = 0; 1672 1708 break; 1673 1709 default: 1674 - return 0; 1710 + return; 1675 1711 } 1676 1712 i2c_w(gspca_dev, exp); 1677 - return 0; 1678 1713 } 1679 1714 1680 - static int set_gain(struct gspca_dev *gspca_dev) 1715 + static void set_gain(struct gspca_dev *gspca_dev) 1681 1716 { 1682 1717 struct sd *sd = (struct sd *) gspca_dev; 1683 1718 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d}; 1719 + int g; 1720 + 1721 + g = sd->ctrls[GAIN].val; 1684 1722 switch (sd->sensor) { 1685 1723 case SENSOR_OV7660: 1686 1724 case SENSOR_OV7670: ··· 1690 1724 case SENSOR_OV9655: 1691 1725 case SENSOR_OV9650: 1692 1726 gain[0] |= (2 << 4); 1693 - gain[3] = ov_gain[sd->gain]; 1727 + gain[3] = ov_gain[g]; 1694 1728 break; 1695 1729 case SENSOR_MT9V011: 1696 1730 gain[0] |= (3 << 4); 1697 1731 gain[2] = 0x35; 1698 - gain[3] = micron1_gain[sd->gain] >> 8; 1699 - gain[4] = micron1_gain[sd->gain] & 0xff; 1732 + gain[3] = micron1_gain[g] >> 8; 1733 + gain[4] = micron1_gain[g]; 1700 1734 break; 1701 1735 case SENSOR_MT9V112: 1702 1736 gain[0] |= (3 << 4); 1703 1737 gain[2] = 0x2f; 1704 - gain[3] = micron1_gain[sd->gain] >> 8; 1705 - gain[4] = micron1_gain[sd->gain] & 0xff; 1738 + gain[3] = micron1_gain[g] >> 8; 1739 + gain[4] = micron1_gain[g]; 1706 1740 break; 1707 1741 case SENSOR_MT9M001: 1708 1742 gain[0] |= (3 << 4); 1709 1743 gain[2] = 0x2f; 1710 - gain[3] = micron2_gain[sd->gain] >> 8; 1711 - gain[4] = micron2_gain[sd->gain] & 0xff; 1744 + gain[3] = micron2_gain[g] >> 8; 1745 + gain[4] = micron2_gain[g]; 1712 1746 break; 1713 1747 case SENSOR_HV7131R: 1714 1748 gain[0] |= (2 << 4); 1715 1749 gain[2] = 0x30; 1716 - gain[3] = hv7131r_gain[sd->gain]; 1750 + gain[3] = hv7131r_gain[g]; 1717 1751 break; 1718 1752 default: 1719 - return 0; 1753 + return; 1720 1754 } 1721 1755 i2c_w(gspca_dev, gain); 1722 - return 0; 1723 1756 } 1724 1757 1725 - static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val) 1758 + static void set_quality(struct gspca_dev *gspca_dev) 1726 1759 { 1727 1760 struct sd *sd = (struct sd *) gspca_dev; 1728 1761 1729 - sd->brightness = val; 1730 - if (gspca_dev->streaming) 1731 - return set_cmatrix(gspca_dev); 1732 - return 0; 1733 - } 1734 - 1735 - static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val) 1736 - { 1737 - struct sd *sd = (struct sd *) gspca_dev; 1738 - *val = sd->brightness; 1739 - return 0; 1740 - } 1741 - 1742 - 1743 - static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val) 1744 - { 1745 - struct sd *sd = (struct sd *) gspca_dev; 1746 - 1747 - sd->contrast = val; 1748 - if (gspca_dev->streaming) 1749 - return set_cmatrix(gspca_dev); 1750 - return 0; 1751 - } 1752 - 1753 - static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val) 1754 - { 1755 - struct sd *sd = (struct sd *) gspca_dev; 1756 - *val = sd->contrast; 1757 - return 0; 1758 - } 1759 - 1760 - static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val) 1761 - { 1762 - struct sd *sd = (struct sd *) gspca_dev; 1763 - 1764 - sd->saturation = val; 1765 - if (gspca_dev->streaming) 1766 - return set_cmatrix(gspca_dev); 1767 - return 0; 1768 - } 1769 - 1770 - static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val) 1771 - { 1772 - struct sd *sd = (struct sd *) gspca_dev; 1773 - *val = sd->saturation; 1774 - return 0; 1775 - } 1776 - 1777 - static int sd_sethue(struct gspca_dev *gspca_dev, s32 val) 1778 - { 1779 - struct sd *sd = (struct sd *) gspca_dev; 1780 - 1781 - sd->hue = val; 1782 - if (gspca_dev->streaming) 1783 - return set_cmatrix(gspca_dev); 1784 - return 0; 1785 - } 1786 - 1787 - static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val) 1788 - { 1789 - struct sd *sd = (struct sd *) gspca_dev; 1790 - *val = sd->hue; 1791 - return 0; 1792 - } 1793 - 1794 - static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val) 1795 - { 1796 - struct sd *sd = (struct sd *) gspca_dev; 1797 - 1798 - sd->gamma = val; 1799 - if (gspca_dev->streaming) 1800 - return set_gamma(gspca_dev); 1801 - return 0; 1802 - } 1803 - 1804 - static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val) 1805 - { 1806 - struct sd *sd = (struct sd *) gspca_dev; 1807 - *val = sd->gamma; 1808 - return 0; 1809 - } 1810 - 1811 - static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val) 1812 - { 1813 - struct sd *sd = (struct sd *) gspca_dev; 1814 - 1815 - sd->red = val; 1816 - if (gspca_dev->streaming) 1817 - return set_redblue(gspca_dev); 1818 - return 0; 1819 - } 1820 - 1821 - static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val) 1822 - { 1823 - struct sd *sd = (struct sd *) gspca_dev; 1824 - *val = sd->red; 1825 - return 0; 1826 - } 1827 - 1828 - static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val) 1829 - { 1830 - struct sd *sd = (struct sd *) gspca_dev; 1831 - 1832 - sd->blue = val; 1833 - if (gspca_dev->streaming) 1834 - return set_redblue(gspca_dev); 1835 - return 0; 1836 - } 1837 - 1838 - static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val) 1839 - { 1840 - struct sd *sd = (struct sd *) gspca_dev; 1841 - *val = sd->blue; 1842 - return 0; 1843 - } 1844 - 1845 - static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val) 1846 - { 1847 - struct sd *sd = (struct sd *) gspca_dev; 1848 - 1849 - sd->hflip = val; 1850 - if (gspca_dev->streaming) 1851 - return set_hvflip(gspca_dev); 1852 - return 0; 1853 - } 1854 - 1855 - static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val) 1856 - { 1857 - struct sd *sd = (struct sd *) gspca_dev; 1858 - *val = sd->hflip; 1859 - return 0; 1860 - } 1861 - 1862 - static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val) 1863 - { 1864 - struct sd *sd = (struct sd *) gspca_dev; 1865 - 1866 - sd->vflip = val; 1867 - if (gspca_dev->streaming) 1868 - return set_hvflip(gspca_dev); 1869 - return 0; 1870 - } 1871 - 1872 - static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val) 1873 - { 1874 - struct sd *sd = (struct sd *) gspca_dev; 1875 - *val = sd->vflip; 1876 - return 0; 1877 - } 1878 - 1879 - static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val) 1880 - { 1881 - struct sd *sd = (struct sd *) gspca_dev; 1882 - 1883 - sd->exposure = val; 1884 - if (gspca_dev->streaming) 1885 - return set_exposure(gspca_dev); 1886 - return 0; 1887 - } 1888 - 1889 - static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val) 1890 - { 1891 - struct sd *sd = (struct sd *) gspca_dev; 1892 - *val = sd->exposure; 1893 - return 0; 1894 - } 1895 - 1896 - static int sd_setgain(struct gspca_dev *gspca_dev, s32 val) 1897 - { 1898 - struct sd *sd = (struct sd *) gspca_dev; 1899 - 1900 - sd->gain = val; 1901 - if (gspca_dev->streaming) 1902 - return set_gain(gspca_dev); 1903 - return 0; 1904 - } 1905 - 1906 - static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val) 1907 - { 1908 - struct sd *sd = (struct sd *) gspca_dev; 1909 - *val = sd->gain; 1910 - return 0; 1911 - } 1912 - 1913 - static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val) 1914 - { 1915 - struct sd *sd = (struct sd *) gspca_dev; 1916 - sd->auto_exposure = val; 1917 - return 0; 1918 - } 1919 - 1920 - static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val) 1921 - { 1922 - struct sd *sd = (struct sd *) gspca_dev; 1923 - *val = sd->auto_exposure; 1924 - return 0; 1762 + jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val); 1763 + reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */ 1764 + reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */ 1765 + reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); 1766 + reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); 1767 + reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */ 1768 + reg_w1(gspca_dev, 0x10e0, sd->fmt); 1769 + sd->fmt ^= 0x0c; /* invert QTAB use + write */ 1770 + reg_w1(gspca_dev, 0x10e0, sd->fmt); 1925 1771 } 1926 1772 1927 1773 #ifdef CONFIG_VIDEO_ADV_DEBUG ··· 1741 1963 struct v4l2_dbg_register *reg) 1742 1964 { 1743 1965 struct sd *sd = (struct sd *) gspca_dev; 1966 + 1744 1967 switch (reg->match.type) { 1745 1968 case V4L2_CHIP_MATCH_HOST: 1746 1969 if (reg->match.addr != 0) 1747 1970 return -EINVAL; 1748 1971 if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1749 1972 return -EINVAL; 1750 - if (reg_r(gspca_dev, reg->reg, 1) < 0) 1751 - return -EINVAL; 1973 + reg_r(gspca_dev, reg->reg, 1); 1752 1974 reg->val = gspca_dev->usb_buf[0]; 1753 - return 0; 1975 + return gspca_dev->usb_err; 1754 1976 case V4L2_CHIP_MATCH_I2C_ADDR: 1755 1977 if (reg->match.addr != sd->i2c_addr) 1756 1978 return -EINVAL; 1757 1979 if (sd->sensor >= SENSOR_MT9V011 && 1758 1980 sd->sensor <= SENSOR_MT9M112) { 1759 - if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0) 1760 - return -EINVAL; 1981 + i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val); 1761 1982 } else { 1762 - if (i2c_r1(gspca_dev, reg->reg, (u8 *)&reg->val) < 0) 1763 - return -EINVAL; 1983 + i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val); 1764 1984 } 1765 - return 0; 1985 + return gspca_dev->usb_err; 1766 1986 } 1767 1987 return -EINVAL; 1768 1988 } ··· 1769 1993 struct v4l2_dbg_register *reg) 1770 1994 { 1771 1995 struct sd *sd = (struct sd *) gspca_dev; 1996 + 1772 1997 switch (reg->match.type) { 1773 1998 case V4L2_CHIP_MATCH_HOST: 1774 1999 if (reg->match.addr != 0) 1775 2000 return -EINVAL; 1776 2001 if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1777 2002 return -EINVAL; 1778 - if (reg_w1(gspca_dev, reg->reg, reg->val) < 0) 1779 - return -EINVAL; 1780 - return 0; 2003 + reg_w1(gspca_dev, reg->reg, reg->val); 2004 + return gspca_dev->usb_err; 1781 2005 case V4L2_CHIP_MATCH_I2C_ADDR: 1782 2006 if (reg->match.addr != sd->i2c_addr) 1783 2007 return -EINVAL; 1784 2008 if (sd->sensor >= SENSOR_MT9V011 && 1785 2009 sd->sensor <= SENSOR_MT9M112) { 1786 - if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0) 1787 - return -EINVAL; 2010 + i2c_w2(gspca_dev, reg->reg, reg->val); 1788 2011 } else { 1789 - if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0) 1790 - return -EINVAL; 2012 + i2c_w1(gspca_dev, reg->reg, reg->val); 1791 2013 } 1792 - return 0; 2014 + return gspca_dev->usb_err; 1793 2015 } 1794 2016 return -EINVAL; 1795 2017 } ··· 1824 2050 cam = &gspca_dev->cam; 1825 2051 cam->needs_full_bandwidth = 1; 1826 2052 1827 - sd->sensor = (id->driver_info >> 8) & 0xff; 1828 - sd->i2c_addr = id->driver_info & 0xff; 1829 - sd->flags = (id->driver_info >> 16) & 0xff; 2053 + sd->sensor = id->driver_info >> 8; 2054 + sd->i2c_addr = id->driver_info; 2055 + sd->flags = id->driver_info >> 16; 1830 2056 1831 2057 switch (sd->sensor) { 1832 2058 case SENSOR_MT9M112: ··· 1850 2076 sd->older_step = 0; 1851 2077 sd->exposure_step = 16; 1852 2078 1853 - sd->brightness = BRIGHTNESS_DEFAULT; 1854 - sd->contrast = CONTRAST_DEFAULT; 1855 - sd->saturation = SATURATION_DEFAULT; 1856 - sd->hue = HUE_DEFAULT; 1857 - sd->gamma = GAMMA_DEFAULT; 1858 - sd->red = RED_DEFAULT; 1859 - sd->blue = BLUE_DEFAULT; 2079 + gspca_dev->cam.ctrls = sd->ctrls; 1860 2080 1861 - sd->hflip = HFLIP_DEFAULT; 1862 - sd->vflip = VFLIP_DEFAULT; 1863 - sd->exposure = EXPOSURE_DEFAULT; 1864 - sd->gain = GAIN_DEFAULT; 1865 - sd->auto_exposure = AUTO_EXPOSURE_DEFAULT; 1866 - 1867 - sd->quality = 95; 2081 + INIT_WORK(&sd->work, qual_upd); 1868 2082 1869 2083 return 0; 1870 2084 } ··· 1867 2105 1868 2106 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) { 1869 2107 value = bridge_init[i][1]; 1870 - if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) { 2108 + reg_w(gspca_dev, bridge_init[i][0], &value, 1); 2109 + if (gspca_dev->usb_err < 0) { 1871 2110 pr_err("Device initialization failed\n"); 1872 - return -ENODEV; 2111 + return gspca_dev->usb_err; 1873 2112 } 1874 2113 } 1875 2114 ··· 1879 2116 else 1880 2117 reg_w1(gspca_dev, 0x1006, 0x20); 1881 2118 1882 - if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) { 2119 + reg_w(gspca_dev, 0x10c0, i2c_init, 9); 2120 + if (gspca_dev->usb_err < 0) { 1883 2121 pr_err("Device initialization failed\n"); 1884 - return -ENODEV; 2122 + return gspca_dev->usb_err; 1885 2123 } 1886 2124 1887 2125 switch (sd->sensor) { 1888 2126 case SENSOR_OV9650: 1889 - if (ov9650_init_sensor(gspca_dev) < 0) 1890 - return -ENODEV; 2127 + ov9650_init_sensor(gspca_dev); 2128 + if (gspca_dev->usb_err < 0) 2129 + break; 1891 2130 pr_info("OV9650 sensor detected\n"); 1892 2131 break; 1893 2132 case SENSOR_OV9655: 1894 - if (ov9655_init_sensor(gspca_dev) < 0) 1895 - return -ENODEV; 2133 + ov9655_init_sensor(gspca_dev); 2134 + if (gspca_dev->usb_err < 0) 2135 + break; 1896 2136 pr_info("OV9655 sensor detected\n"); 1897 2137 break; 1898 2138 case SENSOR_SOI968: 1899 - if (soi968_init_sensor(gspca_dev) < 0) 1900 - return -ENODEV; 2139 + soi968_init_sensor(gspca_dev); 2140 + if (gspca_dev->usb_err < 0) 2141 + break; 1901 2142 pr_info("SOI968 sensor detected\n"); 1902 2143 break; 1903 2144 case SENSOR_OV7660: 1904 - if (ov7660_init_sensor(gspca_dev) < 0) 1905 - return -ENODEV; 2145 + ov7660_init_sensor(gspca_dev); 2146 + if (gspca_dev->usb_err < 0) 2147 + break; 1906 2148 pr_info("OV7660 sensor detected\n"); 1907 2149 break; 1908 2150 case SENSOR_OV7670: 1909 - if (ov7670_init_sensor(gspca_dev) < 0) 1910 - return -ENODEV; 2151 + ov7670_init_sensor(gspca_dev); 2152 + if (gspca_dev->usb_err < 0) 2153 + break; 1911 2154 pr_info("OV7670 sensor detected\n"); 1912 2155 break; 1913 2156 case SENSOR_MT9VPRB: 1914 - if (mt9v_init_sensor(gspca_dev) < 0) 1915 - return -ENODEV; 2157 + mt9v_init_sensor(gspca_dev); 2158 + if (gspca_dev->usb_err < 0) 2159 + break; 2160 + pr_info("MT9VPRB sensor detected\n"); 1916 2161 break; 1917 2162 case SENSOR_MT9M111: 1918 - if (mt9m111_init_sensor(gspca_dev) < 0) 1919 - return -ENODEV; 2163 + mt9m111_init_sensor(gspca_dev); 2164 + if (gspca_dev->usb_err < 0) 2165 + break; 1920 2166 pr_info("MT9M111 sensor detected\n"); 1921 2167 break; 1922 2168 case SENSOR_MT9M112: 1923 - if (mt9m112_init_sensor(gspca_dev) < 0) 1924 - return -ENODEV; 2169 + mt9m112_init_sensor(gspca_dev); 2170 + if (gspca_dev->usb_err < 0) 2171 + break; 1925 2172 pr_info("MT9M112 sensor detected\n"); 1926 2173 break; 1927 2174 case SENSOR_MT9M001: 1928 - if (mt9m001_init_sensor(gspca_dev) < 0) 1929 - return -ENODEV; 2175 + mt9m001_init_sensor(gspca_dev); 2176 + if (gspca_dev->usb_err < 0) 2177 + break; 1930 2178 break; 1931 2179 case SENSOR_HV7131R: 1932 - if (hv7131r_init_sensor(gspca_dev) < 0) 1933 - return -ENODEV; 2180 + hv7131r_init_sensor(gspca_dev); 2181 + if (gspca_dev->usb_err < 0) 2182 + break; 1934 2183 pr_info("HV7131R sensor detected\n"); 1935 2184 break; 1936 2185 default: 1937 - pr_info("Unsupported Sensor\n"); 1938 - return -ENODEV; 2186 + pr_err("Unsupported sensor\n"); 2187 + gspca_dev->usb_err = -ENODEV; 1939 2188 } 1940 2189 1941 - return 0; 2190 + return gspca_dev->usb_err; 1942 2191 } 1943 2192 1944 2193 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) 1945 2194 { 1946 2195 struct sd *sd = (struct sd *) gspca_dev; 1947 2196 u8 value; 2197 + 1948 2198 switch (sd->sensor) { 1949 2199 case SENSOR_SOI968: 1950 2200 if (mode & MODE_SXGA) { ··· 2040 2264 break; 2041 2265 default: /* >= 640x480 */ 2042 2266 gspca_dev->alt = 9; 2267 + break; 2043 2268 } 2044 2269 } 2045 2270 ··· 2067 2290 2068 2291 jpeg_define(sd->jpeg_hdr, height, width, 2069 2292 0x21); 2070 - jpeg_set_qual(sd->jpeg_hdr, sd->quality); 2293 + jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val); 2071 2294 2072 2295 if (mode & MODE_RAW) 2073 2296 fmt = 0x2d; 2074 2297 else if (mode & MODE_JPEG) 2075 - fmt = 0x2c; 2298 + fmt = 0x24; 2076 2299 else 2077 2300 fmt = 0x2f; /* YUV 420 */ 2301 + sd->fmt = fmt; 2078 2302 2079 2303 switch (mode & SCALE_MASK) { 2080 2304 case SCALE_1280x1024: ··· 2112 2334 set_hvflip(gspca_dev); 2113 2335 2114 2336 reg_w1(gspca_dev, 0x1007, 0x20); 2337 + reg_w1(gspca_dev, 0x1061, 0x03); 2115 2338 2116 - reg_r(gspca_dev, 0x1061, 1); 2117 - reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02); 2118 - return 0; 2339 + /* if JPEG, prepare the compression quality update */ 2340 + if (mode & MODE_JPEG) { 2341 + sd->pktsz = sd->npkt = 0; 2342 + sd->nchg = 0; 2343 + sd->work_thread = 2344 + create_singlethread_workqueue(KBUILD_MODNAME); 2345 + } 2346 + 2347 + return gspca_dev->usb_err; 2119 2348 } 2120 2349 2121 2350 static void sd_stopN(struct gspca_dev *gspca_dev) 2122 2351 { 2123 2352 reg_w1(gspca_dev, 0x1007, 0x00); 2353 + reg_w1(gspca_dev, 0x1061, 0x01); 2354 + } 2124 2355 2125 - reg_r(gspca_dev, 0x1061, 1); 2126 - reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02); 2356 + /* called on streamoff with alt==0 and on disconnect */ 2357 + /* the usb_lock is held at entry - restore on exit */ 2358 + static void sd_stop0(struct gspca_dev *gspca_dev) 2359 + { 2360 + struct sd *sd = (struct sd *) gspca_dev; 2361 + 2362 + if (sd->work_thread != NULL) { 2363 + mutex_unlock(&gspca_dev->usb_lock); 2364 + destroy_workqueue(sd->work_thread); 2365 + mutex_lock(&gspca_dev->usb_lock); 2366 + sd->work_thread = NULL; 2367 + } 2127 2368 } 2128 2369 2129 2370 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) ··· 2156 2359 * and exposure steps 2157 2360 */ 2158 2361 if (avg_lum < MIN_AVG_LUM) { 2159 - if (sd->exposure > 0x1770) 2362 + if (sd->ctrls[EXPOSURE].val > 0x1770) 2160 2363 return; 2161 2364 2162 - new_exp = sd->exposure + sd->exposure_step; 2365 + new_exp = sd->ctrls[EXPOSURE].val + sd->exposure_step; 2163 2366 if (new_exp > 0x1770) 2164 2367 new_exp = 0x1770; 2165 2368 if (new_exp < 0x10) 2166 2369 new_exp = 0x10; 2167 - sd->exposure = new_exp; 2370 + sd->ctrls[EXPOSURE].val = new_exp; 2168 2371 set_exposure(gspca_dev); 2169 2372 2170 2373 sd->older_step = sd->old_step; ··· 2176 2379 sd->exposure_step += 2; 2177 2380 } 2178 2381 if (avg_lum > MAX_AVG_LUM) { 2179 - if (sd->exposure < 0x10) 2382 + if (sd->ctrls[EXPOSURE].val < 0x10) 2180 2383 return; 2181 - new_exp = sd->exposure - sd->exposure_step; 2384 + new_exp = sd->ctrls[EXPOSURE].val - sd->exposure_step; 2182 2385 if (new_exp > 0x1700) 2183 2386 new_exp = 0x1770; 2184 2387 if (new_exp < 0x10) 2185 2388 new_exp = 0x10; 2186 - sd->exposure = new_exp; 2389 + sd->ctrls[EXPOSURE].val = new_exp; 2187 2390 set_exposure(gspca_dev); 2188 2391 sd->older_step = sd->old_step; 2189 2392 sd->old_step = 0; ··· 2200 2403 struct sd *sd = (struct sd *) gspca_dev; 2201 2404 2202 2405 if (avg_lum < MIN_AVG_LUM) { 2203 - if (sd->gain + 1 <= 28) { 2204 - sd->gain++; 2406 + if (sd->ctrls[GAIN].val + 1 <= 28) { 2407 + sd->ctrls[GAIN].val++; 2205 2408 set_gain(gspca_dev); 2206 2409 } 2207 2410 } 2208 2411 if (avg_lum > MAX_AVG_LUM) { 2209 - if (sd->gain > 0) { 2210 - sd->gain--; 2412 + if (sd->ctrls[GAIN].val > 0) { 2413 + sd->ctrls[GAIN].val--; 2211 2414 set_gain(gspca_dev); 2212 2415 } 2213 2416 } ··· 2218 2421 struct sd *sd = (struct sd *) gspca_dev; 2219 2422 int avg_lum; 2220 2423 2221 - if (!sd->auto_exposure) 2424 + if (!sd->ctrls[AUTOGAIN].val) 2222 2425 return; 2223 2426 2224 2427 avg_lum = atomic_read(&sd->avg_lum); ··· 2228 2431 do_autoexposure(gspca_dev, avg_lum); 2229 2432 } 2230 2433 2434 + /* JPEG quality update */ 2435 + /* This function is executed from a work queue. */ 2436 + static void qual_upd(struct work_struct *work) 2437 + { 2438 + struct sd *sd = container_of(work, struct sd, work); 2439 + struct gspca_dev *gspca_dev = &sd->gspca_dev; 2440 + 2441 + mutex_lock(&gspca_dev->usb_lock); 2442 + PDEBUG(D_STREAM, "qual_upd %d%%", sd->ctrls[QUALITY].val); 2443 + set_quality(gspca_dev); 2444 + mutex_unlock(&gspca_dev->usb_lock); 2445 + } 2446 + 2231 2447 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 2232 2448 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, 2233 2449 u8 *data, /* interrupt packet */ 2234 2450 int len) /* interrupt packet length */ 2235 2451 { 2236 2452 struct sd *sd = (struct sd *) gspca_dev; 2237 - int ret = -EINVAL; 2453 + 2238 2454 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) { 2239 - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); 2240 - input_sync(gspca_dev->input_dev); 2241 - input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); 2242 - input_sync(gspca_dev->input_dev); 2243 - ret = 0; 2455 + input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); 2456 + input_sync(gspca_dev->input_dev); 2457 + input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); 2458 + input_sync(gspca_dev->input_dev); 2459 + return 0; 2244 2460 } 2245 - return ret; 2461 + return -EINVAL; 2246 2462 } 2247 2463 #endif 2464 + 2465 + /* check the JPEG compression */ 2466 + static void transfer_check(struct gspca_dev *gspca_dev, 2467 + u8 *data) 2468 + { 2469 + struct sd *sd = (struct sd *) gspca_dev; 2470 + int new_qual, r; 2471 + 2472 + new_qual = 0; 2473 + 2474 + /* if USB error, discard the frame and decrease the quality */ 2475 + if (data[6] & 0x08) { /* USB FIFO full */ 2476 + gspca_dev->last_packet_type = DISCARD_PACKET; 2477 + new_qual = -5; 2478 + } else { 2479 + 2480 + /* else, compute the filling rate and a new JPEG quality */ 2481 + r = (sd->pktsz * 100) / 2482 + (sd->npkt * 2483 + gspca_dev->urb[0]->iso_frame_desc[0].length); 2484 + if (r >= 85) 2485 + new_qual = -3; 2486 + else if (r < 75) 2487 + new_qual = 2; 2488 + } 2489 + if (new_qual != 0) { 2490 + sd->nchg += new_qual; 2491 + if (sd->nchg < -6 || sd->nchg >= 12) { 2492 + sd->nchg = 0; 2493 + new_qual += sd->ctrls[QUALITY].val; 2494 + if (new_qual < QUALITY_MIN) 2495 + new_qual = QUALITY_MIN; 2496 + else if (new_qual > QUALITY_MAX) 2497 + new_qual = QUALITY_MAX; 2498 + if (new_qual != sd->ctrls[QUALITY].val) { 2499 + sd->ctrls[QUALITY].val = new_qual; 2500 + queue_work(sd->work_thread, &sd->work); 2501 + } 2502 + } 2503 + } else { 2504 + sd->nchg = 0; 2505 + } 2506 + sd->pktsz = sd->npkt = 0; 2507 + } 2248 2508 2249 2509 static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2250 2510 u8 *data, /* isoc packet */ 2251 2511 int len) /* iso packet length */ 2252 2512 { 2253 2513 struct sd *sd = (struct sd *) gspca_dev; 2254 - int avg_lum; 2514 + int avg_lum, is_jpeg; 2255 2515 static u8 frame_header[] = 2256 2516 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; 2257 - if (len == 64 && memcmp(data, frame_header, 6) == 0) { 2517 + 2518 + is_jpeg = (sd->fmt & 0x03) == 0; 2519 + if (len >= 64 && memcmp(data, frame_header, 6) == 0) { 2258 2520 avg_lum = ((data[35] >> 2) & 3) | 2259 2521 (data[20] << 2) | 2260 2522 (data[19] << 10); ··· 2340 2484 (data[33] << 10); 2341 2485 avg_lum >>= 9; 2342 2486 atomic_set(&sd->avg_lum, avg_lum); 2487 + 2488 + if (is_jpeg) 2489 + transfer_check(gspca_dev, data); 2490 + 2343 2491 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 2344 - return; 2492 + len -= 64; 2493 + if (len == 0) 2494 + return; 2495 + data += 64; 2345 2496 } 2346 2497 if (gspca_dev->last_packet_type == LAST_PACKET) { 2347 - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv 2348 - & MODE_JPEG) { 2498 + if (is_jpeg) { 2349 2499 gspca_frame_add(gspca_dev, FIRST_PACKET, 2350 2500 sd->jpeg_hdr, JPEG_HDR_SZ); 2351 2501 gspca_frame_add(gspca_dev, INTER_PACKET, ··· 2361 2499 data, len); 2362 2500 } 2363 2501 } else { 2502 + /* if JPEG, count the packets and their size */ 2503 + if (is_jpeg) { 2504 + sd->npkt++; 2505 + sd->pktsz += len; 2506 + } 2364 2507 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 2365 2508 } 2366 2509 } 2367 2510 2368 2511 /* sub-driver description */ 2369 2512 static const struct sd_desc sd_desc = { 2370 - .name = MODULE_NAME, 2513 + .name = KBUILD_MODNAME, 2371 2514 .ctrls = sd_ctrls, 2372 2515 .nctrls = ARRAY_SIZE(sd_ctrls), 2373 2516 .config = sd_config, ··· 2380 2513 .isoc_init = sd_isoc_init, 2381 2514 .start = sd_start, 2382 2515 .stopN = sd_stopN, 2516 + .stop0 = sd_stop0, 2383 2517 .pkt_scan = sd_pkt_scan, 2384 2518 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 2385 2519 .int_pkt_scan = sd_int_pkt_scan, ··· 2449 2581 } 2450 2582 2451 2583 static struct usb_driver sd_driver = { 2452 - .name = MODULE_NAME, 2584 + .name = KBUILD_MODNAME, 2453 2585 .id_table = device_table, 2454 2586 .probe = sd_probe, 2455 2587 .disconnect = gspca_disconnect,
+140 -45
drivers/media/video/gspca/sonixj.c
··· 39 39 BLUE, 40 40 RED, 41 41 GAMMA, 42 + EXPOSURE, 42 43 AUTOGAIN, 44 + GAIN, 43 45 HFLIP, 44 46 VFLIP, 45 47 SHARPNESS, ··· 133 131 static void setcolors(struct gspca_dev *gspca_dev); 134 132 static void setredblue(struct gspca_dev *gspca_dev); 135 133 static void setgamma(struct gspca_dev *gspca_dev); 136 - static void setautogain(struct gspca_dev *gspca_dev); 134 + static void setexposure(struct gspca_dev *gspca_dev); 135 + static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 136 + static void setgain(struct gspca_dev *gspca_dev); 137 137 static void sethvflip(struct gspca_dev *gspca_dev); 138 138 static void setsharpness(struct gspca_dev *gspca_dev); 139 139 static void setillum(struct gspca_dev *gspca_dev); ··· 217 213 }, 218 214 .set_control = setgamma 219 215 }, 216 + [EXPOSURE] = { 217 + { 218 + .id = V4L2_CID_EXPOSURE, 219 + .type = V4L2_CTRL_TYPE_INTEGER, 220 + .name = "Exposure", 221 + .minimum = 500, 222 + .maximum = 1500, 223 + .step = 1, 224 + .default_value = 1024 225 + }, 226 + .set_control = setexposure 227 + }, 220 228 [AUTOGAIN] = { 221 229 { 222 230 .id = V4L2_CID_AUTOGAIN, ··· 239 223 .step = 1, 240 224 .default_value = 1 241 225 }, 242 - .set_control = setautogain 226 + .set = sd_setautogain, 227 + }, 228 + [GAIN] = { 229 + { 230 + .id = V4L2_CID_GAIN, 231 + .type = V4L2_CTRL_TYPE_INTEGER, 232 + .name = "Gain", 233 + .minimum = 4, 234 + .maximum = 49, 235 + .step = 1, 236 + .default_value = 15 237 + }, 238 + .set_control = setgain 243 239 }, 244 240 [HFLIP] = { 245 241 { ··· 318 290 319 291 /* table of the disabled controls */ 320 292 static const __u32 ctrl_dis[] = { 321 - [SENSOR_ADCM1700] = (1 << AUTOGAIN) | 293 + [SENSOR_ADCM1700] = (1 << EXPOSURE) | 294 + (1 << AUTOGAIN) | 295 + (1 << GAIN) | 322 296 (1 << HFLIP) | 323 297 (1 << VFLIP) | 324 298 (1 << FREQ), 325 299 326 - [SENSOR_GC0307] = (1 << HFLIP) | 300 + [SENSOR_GC0307] = (1 << EXPOSURE) | 301 + (1 << GAIN) | 302 + (1 << HFLIP) | 327 303 (1 << VFLIP) | 328 304 (1 << FREQ), 329 305 330 - [SENSOR_HV7131R] = (1 << HFLIP) | 306 + [SENSOR_HV7131R] = (1 << EXPOSURE) | 307 + (1 << GAIN) | 308 + (1 << HFLIP) | 331 309 (1 << FREQ), 332 310 333 - [SENSOR_MI0360] = (1 << HFLIP) | 311 + [SENSOR_MI0360] = (1 << EXPOSURE) | 312 + (1 << GAIN) | 313 + (1 << HFLIP) | 334 314 (1 << VFLIP) | 335 315 (1 << FREQ), 336 316 337 - [SENSOR_MI0360B] = (1 << HFLIP) | 317 + [SENSOR_MI0360B] = (1 << EXPOSURE) | 318 + (1 << GAIN) | 319 + (1 << HFLIP) | 338 320 (1 << VFLIP) | 339 321 (1 << FREQ), 340 322 341 - [SENSOR_MO4000] = (1 << HFLIP) | 323 + [SENSOR_MO4000] = (1 << EXPOSURE) | 324 + (1 << GAIN) | 325 + (1 << HFLIP) | 342 326 (1 << VFLIP) | 343 327 (1 << FREQ), 344 328 345 - [SENSOR_MT9V111] = (1 << HFLIP) | 329 + [SENSOR_MT9V111] = (1 << EXPOSURE) | 330 + (1 << GAIN) | 331 + (1 << HFLIP) | 346 332 (1 << VFLIP) | 347 333 (1 << FREQ), 348 334 349 - [SENSOR_OM6802] = (1 << HFLIP) | 335 + [SENSOR_OM6802] = (1 << EXPOSURE) | 336 + (1 << GAIN) | 337 + (1 << HFLIP) | 350 338 (1 << VFLIP) | 351 339 (1 << FREQ), 352 340 353 - [SENSOR_OV7630] = (1 << HFLIP), 341 + [SENSOR_OV7630] = (1 << EXPOSURE) | 342 + (1 << GAIN) | 343 + (1 << HFLIP), 354 344 355 - [SENSOR_OV7648] = (1 << HFLIP), 345 + [SENSOR_OV7648] = (1 << EXPOSURE) | 346 + (1 << GAIN) | 347 + (1 << HFLIP), 356 348 357 - [SENSOR_OV7660] = (1 << AUTOGAIN) | 349 + [SENSOR_OV7660] = (1 << EXPOSURE) | 350 + (1 << AUTOGAIN) | 351 + (1 << GAIN) | 358 352 (1 << HFLIP) | 359 353 (1 << VFLIP), 360 354 361 - [SENSOR_PO1030] = (1 << AUTOGAIN) | 355 + [SENSOR_PO1030] = (1 << EXPOSURE) | 356 + (1 << AUTOGAIN) | 357 + (1 << GAIN) | 362 358 (1 << HFLIP) | 363 359 (1 << VFLIP) | 364 360 (1 << FREQ), 365 361 366 - [SENSOR_PO2030N] = (1 << AUTOGAIN) | 367 - (1 << FREQ), 362 + [SENSOR_PO2030N] = (1 << FREQ), 368 363 369 - [SENSOR_SOI768] = (1 << AUTOGAIN) | 364 + [SENSOR_SOI768] = (1 << EXPOSURE) | 365 + (1 << AUTOGAIN) | 366 + (1 << GAIN) | 370 367 (1 << HFLIP) | 371 368 (1 << VFLIP) | 372 369 (1 << FREQ), 373 370 374 - [SENSOR_SP80708] = (1 << AUTOGAIN) | 371 + [SENSOR_SP80708] = (1 << EXPOSURE) | 372 + (1 << AUTOGAIN) | 373 + (1 << GAIN) | 375 374 (1 << HFLIP) | 376 375 (1 << VFLIP) | 377 376 (1 << FREQ), ··· 1297 1242 {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10}, 1298 1243 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, 1299 1244 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10}, 1300 - {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, 1301 - {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10}, 1302 - /*after start*/ 1303 - {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10}, 1304 - {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ 1305 - {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10}, 1306 - {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */ 1307 - {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10}, 1308 1245 {} 1309 1246 }; 1310 1247 ··· 1905 1858 return gspca_dev->usb_err; 1906 1859 } 1907 1860 1908 - static u32 setexposure(struct gspca_dev *gspca_dev, 1861 + static u32 expo_adjust(struct gspca_dev *gspca_dev, 1909 1862 u32 expo) 1910 1863 { 1911 1864 struct sd *sd = (struct sd *) gspca_dev; ··· 2029 1982 expo = 0x002dc6c0; 2030 1983 else if (expo < 0x02a0) 2031 1984 expo = 0x02a0; 2032 - sd->exposure = setexposure(gspca_dev, expo); 1985 + sd->exposure = expo_adjust(gspca_dev, expo); 2033 1986 break; 2034 1987 case SENSOR_MI0360: 2035 1988 case SENSOR_MO4000: 2036 1989 expo = brightness << 4; 2037 - sd->exposure = setexposure(gspca_dev, expo); 1990 + sd->exposure = expo_adjust(gspca_dev, expo); 2038 1991 break; 2039 1992 case SENSOR_MI0360B: 2040 1993 expo = brightness << 2; 2041 - sd->exposure = setexposure(gspca_dev, expo); 1994 + sd->exposure = expo_adjust(gspca_dev, expo); 2042 1995 break; 2043 1996 case SENSOR_GC0307: 2044 1997 expo = brightness; 2045 - sd->exposure = setexposure(gspca_dev, expo); 1998 + sd->exposure = expo_adjust(gspca_dev, expo); 2046 1999 return; /* don't set the Y offset */ 2047 2000 case SENSOR_MT9V111: 2048 2001 expo = brightness << 2; 2049 - sd->exposure = setexposure(gspca_dev, expo); 2002 + sd->exposure = expo_adjust(gspca_dev, expo); 2050 2003 return; /* don't set the Y offset */ 2051 2004 case SENSOR_OM6802: 2052 2005 expo = brightness << 2; 2053 - sd->exposure = setexposure(gspca_dev, expo); 2006 + sd->exposure = expo_adjust(gspca_dev, expo); 2054 2007 return; /* Y offset already set */ 2055 2008 } 2056 2009 ··· 2159 2112 reg_w(gspca_dev, 0x20, gamma, sizeof gamma); 2160 2113 } 2161 2114 2115 + static void setexposure(struct gspca_dev *gspca_dev) 2116 + { 2117 + struct sd *sd = (struct sd *) gspca_dev; 2118 + 2119 + if (sd->sensor == SENSOR_PO2030N) { 2120 + u8 rexpo[] = /* 1a: expo H, 1b: expo M */ 2121 + {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10}; 2122 + 2123 + rexpo[3] = sd->ctrls[EXPOSURE].val >> 8; 2124 + i2c_w8(gspca_dev, rexpo); 2125 + msleep(6); 2126 + rexpo[2] = 0x1b; 2127 + rexpo[3] = sd->ctrls[EXPOSURE].val; 2128 + i2c_w8(gspca_dev, rexpo); 2129 + } 2130 + } 2131 + 2162 2132 static void setautogain(struct gspca_dev *gspca_dev) 2163 2133 { 2164 2134 struct sd *sd = (struct sd *) gspca_dev; ··· 2201 2137 sd->ag_cnt = AG_CNT_START; 2202 2138 else 2203 2139 sd->ag_cnt = -1; 2140 + } 2141 + 2142 + static void setgain(struct gspca_dev *gspca_dev) 2143 + { 2144 + struct sd *sd = (struct sd *) gspca_dev; 2145 + 2146 + if (sd->sensor == SENSOR_PO2030N) { 2147 + u8 rgain[] = /* 15: gain */ 2148 + {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15}; 2149 + 2150 + rgain[3] = sd->ctrls[GAIN].val; 2151 + i2c_w8(gspca_dev, rgain); 2152 + } 2204 2153 } 2205 2154 2206 2155 static void sethvflip(struct gspca_dev *gspca_dev) ··· 2700 2623 setcontrast(gspca_dev); 2701 2624 setcolors(gspca_dev); 2702 2625 setautogain(gspca_dev); 2626 + if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) { 2627 + setexposure(gspca_dev); 2628 + setgain(gspca_dev); 2629 + } 2703 2630 setfreq(gspca_dev); 2704 2631 2705 2632 sd->pktsz = sd->npkt = 0; ··· 2800 2719 } 2801 2720 } 2802 2721 2722 + /* !! coarse_grained_expo_autogain is not used !! */ 2723 + #define exp_too_low_cnt bridge 2724 + #define exp_too_high_cnt sensor 2725 + 2726 + #include "autogain_functions.h" 2727 + 2803 2728 static void do_autogain(struct gspca_dev *gspca_dev) 2804 2729 { 2805 2730 struct sd *sd = (struct sd *) gspca_dev; ··· 2823 2736 2824 2737 delta = atomic_read(&sd->avg_lum); 2825 2738 PDEBUG(D_FRAM, "mean lum %d", delta); 2739 + 2740 + if (sd->sensor == SENSOR_PO2030N) { 2741 + auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta, 2742 + 15, 1024); 2743 + return; 2744 + } 2745 + 2826 2746 if (delta < luma_mean - luma_delta || 2827 2747 delta > luma_mean + luma_delta) { 2828 2748 switch (sd->sensor) { ··· 2838 2744 expotimes += (luma_mean - delta) >> 6; 2839 2745 if (expotimes < 0) 2840 2746 expotimes = 0; 2841 - sd->exposure = setexposure(gspca_dev, 2747 + sd->exposure = expo_adjust(gspca_dev, 2842 2748 (unsigned int) expotimes); 2843 2749 break; 2844 2750 case SENSOR_HV7131R: ··· 2846 2752 expotimes += (luma_mean - delta) >> 4; 2847 2753 if (expotimes < 0) 2848 2754 expotimes = 0; 2849 - sd->exposure = setexposure(gspca_dev, 2755 + sd->exposure = expo_adjust(gspca_dev, 2850 2756 (unsigned int) (expotimes << 8)); 2851 2757 break; 2852 2758 case SENSOR_OM6802: ··· 2855 2761 expotimes += (luma_mean - delta) >> 2; 2856 2762 if (expotimes < 0) 2857 2763 expotimes = 0; 2858 - sd->exposure = setexposure(gspca_dev, 2764 + sd->exposure = expo_adjust(gspca_dev, 2859 2765 (unsigned int) expotimes); 2860 2766 setredblue(gspca_dev); 2861 2767 break; ··· 2867 2773 expotimes += (luma_mean - delta) >> 6; 2868 2774 if (expotimes < 0) 2869 2775 expotimes = 0; 2870 - sd->exposure = setexposure(gspca_dev, 2776 + sd->exposure = expo_adjust(gspca_dev, 2871 2777 (unsigned int) expotimes); 2872 2778 setredblue(gspca_dev); 2873 2779 break; ··· 3042 2948 } 3043 2949 } 3044 2950 3045 - static int sd_get_jcomp(struct gspca_dev *gspca_dev, 3046 - struct v4l2_jpegcompression *jcomp) 2951 + static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 3047 2952 { 3048 2953 struct sd *sd = (struct sd *) gspca_dev; 3049 2954 3050 - memset(jcomp, 0, sizeof *jcomp); 3051 - jcomp->quality = sd->quality; 3052 - jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 3053 - | V4L2_JPEG_MARKER_DQT; 3054 - return 0; 2955 + sd->ctrls[AUTOGAIN].val = val; 2956 + if (val) 2957 + gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); 2958 + else 2959 + gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN); 2960 + if (gspca_dev->streaming) 2961 + setautogain(gspca_dev); 2962 + return gspca_dev->usb_err; 3055 2963 } 3056 2964 3057 2965 static int sd_querymenu(struct gspca_dev *gspca_dev, ··· 3108 3012 .stop0 = sd_stop0, 3109 3013 .pkt_scan = sd_pkt_scan, 3110 3014 .dq_callback = do_autogain, 3111 - .get_jcomp = sd_get_jcomp, 3112 3015 .querymenu = sd_querymenu, 3113 3016 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 3114 3017 .int_pkt_scan = sd_int_pkt_scan,
+1 -1
drivers/media/video/gspca/stv06xx/Makefile
··· 6 6 stv06xx_pb0100.o \ 7 7 stv06xx_st6422.o 8 8 9 - ccflags-y += -Idrivers/media/video/gspca 9 + ccflags-y += -I$(srctree)/drivers/media/video/gspca 10 10
+237 -91
drivers/media/video/gspca/zc3xx.c
··· 1 1 /* 2 - * Z-Star/Vimicro zc301/zc302p/vc30x library 2 + * Z-Star/Vimicro zc301/zc302p/vc30x driver 3 3 * 4 - * Copyright (C) 2009-2011 Jean-Francois Moine <http://moinejf.free.fr> 4 + * Copyright (C) 2009-2012 Jean-Francois Moine <http://moinejf.free.fr> 5 5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify ··· 21 21 22 22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 23 23 24 - #define MODULE_NAME "zc3xx" 25 - 26 24 #include <linux/input.h> 27 25 #include "gspca.h" 28 26 #include "jpeg.h" ··· 32 34 33 35 static int force_sensor = -1; 34 36 35 - #define QUANT_VAL 1 /* quantization table */ 37 + #define REG08_DEF 3 /* default JPEG compression (70%) */ 36 38 #include "zc3xx-reg.h" 37 39 38 40 /* controls */ ··· 44 46 AUTOGAIN, 45 47 LIGHTFREQ, 46 48 SHARPNESS, 49 + QUALITY, 47 50 NCTRLS /* number of controls */ 48 51 }; 49 52 ··· 56 57 57 58 struct gspca_ctrl ctrls[NCTRLS]; 58 59 59 - u8 quality; /* image quality */ 60 - #define QUALITY_MIN 50 61 - #define QUALITY_MAX 80 62 - #define QUALITY_DEF 70 60 + struct work_struct work; 61 + struct workqueue_struct *work_thread; 62 + 63 + u8 reg08; /* webcam compression quality */ 63 64 64 65 u8 bridge; 65 66 u8 sensor; /* Type of image sensor chip */ ··· 100 101 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 101 102 static void setlightfreq(struct gspca_dev *gspca_dev); 102 103 static void setsharpness(struct gspca_dev *gspca_dev); 104 + static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val); 103 105 104 106 static const struct ctrl sd_ctrls[NCTRLS] = { 105 107 [BRIGHTNESS] = { ··· 188 188 }, 189 189 .set_control = setsharpness 190 190 }, 191 + [QUALITY] = { 192 + { 193 + .id = V4L2_CID_JPEG_COMPRESSION_QUALITY, 194 + .type = V4L2_CTRL_TYPE_INTEGER, 195 + .name = "Compression Quality", 196 + .minimum = 40, 197 + .maximum = 70, 198 + .step = 1, 199 + .default_value = 70 /* updated in sd_init() */ 200 + }, 201 + .set = sd_setquality 202 + }, 191 203 }; 192 204 193 205 static const struct v4l2_pix_format vga_mode[] = { ··· 240 228 .colorspace = V4L2_COLORSPACE_JPEG, 241 229 .priv = 0}, 242 230 }; 231 + 232 + /* bridge reg08 -> JPEG quality conversion table */ 233 + static u8 jpeg_qual[] = {40, 50, 60, 70, /*80*/}; 243 234 244 235 /* usb exchanges */ 245 236 struct usb_action { ··· 3909 3894 /* Gains */ 3910 3895 {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, 3911 3896 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, 3912 - {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, 3913 3897 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, 3914 3898 /* Auto correction */ 3915 3899 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, ··· 5654 5640 {} 5655 5641 }; 5656 5642 5657 - static u8 reg_r_i(struct gspca_dev *gspca_dev, 5643 + static u8 reg_r(struct gspca_dev *gspca_dev, 5658 5644 u16 index) 5659 5645 { 5660 5646 int ret; ··· 5669 5655 index, gspca_dev->usb_buf, 1, 5670 5656 500); 5671 5657 if (ret < 0) { 5672 - pr_err("reg_r_i err %d\n", ret); 5658 + pr_err("reg_r err %d\n", ret); 5673 5659 gspca_dev->usb_err = ret; 5674 5660 return 0; 5675 5661 } 5676 5662 return gspca_dev->usb_buf[0]; 5677 5663 } 5678 5664 5679 - static u8 reg_r(struct gspca_dev *gspca_dev, 5680 - u16 index) 5681 - { 5682 - u8 ret; 5683 - 5684 - ret = reg_r_i(gspca_dev, index); 5685 - PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret); 5686 - return ret; 5687 - } 5688 - 5689 - static void reg_w_i(struct gspca_dev *gspca_dev, 5665 + static void reg_w(struct gspca_dev *gspca_dev, 5690 5666 u8 value, 5691 5667 u16 index) 5692 5668 { ··· 5696 5692 } 5697 5693 } 5698 5694 5699 - static void reg_w(struct gspca_dev *gspca_dev, 5700 - u8 value, 5701 - u16 index) 5702 - { 5703 - PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value); 5704 - reg_w_i(gspca_dev, value, index); 5705 - } 5706 - 5707 5695 static u16 i2c_read(struct gspca_dev *gspca_dev, 5708 5696 u8 reg) 5709 5697 { ··· 5704 5708 5705 5709 if (gspca_dev->usb_err < 0) 5706 5710 return 0; 5707 - reg_w_i(gspca_dev, reg, 0x0092); 5708 - reg_w_i(gspca_dev, 0x02, 0x0090); /* <- read command */ 5711 + reg_w(gspca_dev, reg, 0x0092); 5712 + reg_w(gspca_dev, 0x02, 0x0090); /* <- read command */ 5709 5713 msleep(20); 5710 - retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5714 + retbyte = reg_r(gspca_dev, 0x0091); /* read status */ 5711 5715 if (retbyte != 0x00) 5712 5716 pr_err("i2c_r status error %02x\n", retbyte); 5713 - retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ 5714 - retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ 5715 - PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)", 5716 - reg, retval, retbyte); 5717 + retval = reg_r(gspca_dev, 0x0095); /* read Lowbyte */ 5718 + retval |= reg_r(gspca_dev, 0x0096) << 8; /* read Hightbyte */ 5717 5719 return retval; 5718 5720 } 5719 5721 ··· 5724 5730 5725 5731 if (gspca_dev->usb_err < 0) 5726 5732 return 0; 5727 - reg_w_i(gspca_dev, reg, 0x92); 5728 - reg_w_i(gspca_dev, valL, 0x93); 5729 - reg_w_i(gspca_dev, valH, 0x94); 5730 - reg_w_i(gspca_dev, 0x01, 0x90); /* <- write command */ 5733 + reg_w(gspca_dev, reg, 0x92); 5734 + reg_w(gspca_dev, valL, 0x93); 5735 + reg_w(gspca_dev, valH, 0x94); 5736 + reg_w(gspca_dev, 0x01, 0x90); /* <- write command */ 5731 5737 msleep(1); 5732 - retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5738 + retbyte = reg_r(gspca_dev, 0x0091); /* read status */ 5733 5739 if (retbyte != 0x00) 5734 5740 pr_err("i2c_w status error %02x\n", retbyte); 5735 - PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)", 5736 - reg, valH, valL, retbyte); 5737 5741 return retbyte; 5738 5742 } 5739 5743 ··· 5898 5906 { 5899 5907 struct sd *sd = (struct sd *) gspca_dev; 5900 5908 5909 + if (sd->sensor != SENSOR_HV7131R) 5910 + return; 5901 5911 sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9) 5902 5912 | (i2c_read(gspca_dev, 0x26) << 1) 5903 5913 | (i2c_read(gspca_dev, 0x27) >> 7); ··· 5910 5916 struct sd *sd = (struct sd *) gspca_dev; 5911 5917 int val; 5912 5918 5919 + if (sd->sensor != SENSOR_HV7131R) 5920 + return; 5913 5921 val = sd->ctrls[EXPOSURE].val; 5914 5922 i2c_write(gspca_dev, 0x25, val >> 9, 0x00); 5915 5923 i2c_write(gspca_dev, 0x26, val >> 1, 0x00); ··· 5921 5925 static void setquality(struct gspca_dev *gspca_dev) 5922 5926 { 5923 5927 struct sd *sd = (struct sd *) gspca_dev; 5924 - u8 frxt; 5928 + s8 reg07; 5925 5929 5930 + reg07 = 0; 5926 5931 switch (sd->sensor) { 5927 - case SENSOR_ADCM2700: 5928 - case SENSOR_GC0305: 5929 - case SENSOR_HV7131B: 5930 - case SENSOR_HV7131R: 5931 5932 case SENSOR_OV7620: 5933 + reg07 = 0x30; 5934 + break; 5935 + case SENSOR_HV7131R: 5932 5936 case SENSOR_PAS202B: 5933 - case SENSOR_PO2030: 5934 - return; 5937 + return; /* done by work queue */ 5935 5938 } 5936 - /*fixme: is it really 0008 0007 0018 for all other sensors? */ 5937 - reg_w(gspca_dev, QUANT_VAL, 0x0008); 5938 - frxt = 0x30; 5939 - reg_w(gspca_dev, frxt, 0x0007); 5940 - #if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2 5941 - frxt = 0xff; 5942 - #elif QUANT_VAL == 3 5943 - frxt = 0xf0; 5944 - #elif QUANT_VAL == 4 5945 - frxt = 0xe0; 5946 - #else 5947 - frxt = 0x20; 5948 - #endif 5949 - reg_w(gspca_dev, frxt, 0x0018); 5939 + reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING); 5940 + if (reg07 != 0) 5941 + reg_w(gspca_dev, reg07, 0x0007); 5950 5942 } 5951 5943 5952 5944 /* Matches the sensor's internal frame rate to the lighting frequency. ··· 6066 6082 else 6067 6083 autoval = 0x02; 6068 6084 reg_w(gspca_dev, autoval, 0x0180); 6085 + } 6086 + 6087 + /* update the transfer parameters */ 6088 + /* This function is executed from a work queue. */ 6089 + /* The exact use of the bridge registers 07 and 08 is not known. 6090 + * The following algorithm has been adapted from ms-win traces */ 6091 + static void transfer_update(struct work_struct *work) 6092 + { 6093 + struct sd *sd = container_of(work, struct sd, work); 6094 + struct gspca_dev *gspca_dev = &sd->gspca_dev; 6095 + int change, good; 6096 + u8 reg07, reg11; 6097 + 6098 + /* synchronize with the main driver and initialize the registers */ 6099 + mutex_lock(&gspca_dev->usb_lock); 6100 + reg07 = 0; /* max */ 6101 + reg_w(gspca_dev, reg07, 0x0007); 6102 + reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING); 6103 + mutex_unlock(&gspca_dev->usb_lock); 6104 + 6105 + good = 0; 6106 + for (;;) { 6107 + msleep(100); 6108 + 6109 + /* get the transfer status */ 6110 + /* the bit 0 of the bridge register 11 indicates overflow */ 6111 + mutex_lock(&gspca_dev->usb_lock); 6112 + if (!gspca_dev->present || !gspca_dev->streaming) 6113 + goto err; 6114 + reg11 = reg_r(gspca_dev, 0x0011); 6115 + if (gspca_dev->usb_err < 0 6116 + || !gspca_dev->present || !gspca_dev->streaming) 6117 + goto err; 6118 + 6119 + change = reg11 & 0x01; 6120 + if (change) { /* overflow */ 6121 + switch (reg07) { 6122 + case 0: /* max */ 6123 + reg07 = sd->sensor == SENSOR_HV7131R 6124 + ? 0x30 : 0x32; 6125 + if (sd->reg08 != 0) { 6126 + change = 3; 6127 + sd->reg08--; 6128 + } 6129 + break; 6130 + case 0x32: 6131 + reg07 -= 4; 6132 + break; 6133 + default: 6134 + reg07 -= 2; 6135 + break; 6136 + case 2: 6137 + change = 0; /* already min */ 6138 + break; 6139 + } 6140 + good = 0; 6141 + } else { /* no overflow */ 6142 + if (reg07 != 0) { /* if not max */ 6143 + good++; 6144 + if (good >= 10) { 6145 + good = 0; 6146 + change = 1; 6147 + reg07 += 2; 6148 + switch (reg07) { 6149 + case 0x30: 6150 + if (sd->sensor == SENSOR_PAS202B) 6151 + reg07 += 2; 6152 + break; 6153 + case 0x32: 6154 + case 0x34: 6155 + reg07 = 0; 6156 + break; 6157 + } 6158 + } 6159 + } else { /* reg07 max */ 6160 + if (sd->reg08 < sizeof jpeg_qual - 1) { 6161 + good++; 6162 + if (good > 10) { 6163 + sd->reg08++; 6164 + change = 2; 6165 + } 6166 + } 6167 + } 6168 + } 6169 + if (change) { 6170 + if (change & 1) { 6171 + reg_w(gspca_dev, reg07, 0x0007); 6172 + if (gspca_dev->usb_err < 0 6173 + || !gspca_dev->present 6174 + || !gspca_dev->streaming) 6175 + goto err; 6176 + } 6177 + if (change & 2) { 6178 + reg_w(gspca_dev, sd->reg08, 6179 + ZC3XX_R008_CLOCKSETTING); 6180 + if (gspca_dev->usb_err < 0 6181 + || !gspca_dev->present 6182 + || !gspca_dev->streaming) 6183 + goto err; 6184 + sd->ctrls[QUALITY].val = jpeg_qual[sd->reg08]; 6185 + jpeg_set_qual(sd->jpeg_hdr, 6186 + jpeg_qual[sd->reg08]); 6187 + } 6188 + } 6189 + mutex_unlock(&gspca_dev->usb_lock); 6190 + } 6191 + return; 6192 + err: 6193 + mutex_unlock(&gspca_dev->usb_lock); 6069 6194 } 6070 6195 6071 6196 static void send_unknown(struct gspca_dev *gspca_dev, int sensor) ··· 6504 6411 sd->sensor = id->driver_info; 6505 6412 6506 6413 gspca_dev->cam.ctrls = sd->ctrls; 6507 - sd->quality = QUALITY_DEF; 6414 + sd->reg08 = REG08_DEF; 6415 + 6416 + INIT_WORK(&sd->work, transfer_update); 6508 6417 6509 6418 return 0; 6510 6419 } ··· 6558 6463 [SENSOR_PB0330] = 1, 6559 6464 [SENSOR_PO2030] = 1, 6560 6465 [SENSOR_TAS5130C] = 1, 6466 + }; 6467 + static const u8 reg08_tb[SENSOR_MAX] = { 6468 + [SENSOR_ADCM2700] = 1, 6469 + [SENSOR_CS2102] = 3, 6470 + [SENSOR_CS2102K] = 3, 6471 + [SENSOR_GC0303] = 2, 6472 + [SENSOR_GC0305] = 3, 6473 + [SENSOR_HDCS2020] = 1, 6474 + [SENSOR_HV7131B] = 3, 6475 + [SENSOR_HV7131R] = 3, 6476 + [SENSOR_ICM105A] = 3, 6477 + [SENSOR_MC501CB] = 3, 6478 + [SENSOR_MT9V111_1] = 3, 6479 + [SENSOR_MT9V111_3] = 3, 6480 + [SENSOR_OV7620] = 1, 6481 + [SENSOR_OV7630C] = 3, 6482 + [SENSOR_PAS106] = 3, 6483 + [SENSOR_PAS202B] = 3, 6484 + [SENSOR_PB0330] = 3, 6485 + [SENSOR_PO2030] = 2, 6486 + [SENSOR_TAS5130C] = 3, 6561 6487 }; 6562 6488 6563 6489 sensor = zcxx_probeSensor(gspca_dev); ··· 6644 6528 case 0x0e: 6645 6529 PDEBUG(D_PROBE, "Find Sensor PAS202B"); 6646 6530 sd->sensor = SENSOR_PAS202B; 6647 - /* sd->sharpness = 1; */ 6648 6531 break; 6649 6532 case 0x0f: 6650 6533 PDEBUG(D_PROBE, "Find Sensor PAS106"); ··· 6731 6616 } 6732 6617 6733 6618 sd->ctrls[GAMMA].def = gamma[sd->sensor]; 6619 + sd->reg08 = reg08_tb[sd->sensor]; 6620 + sd->ctrls[QUALITY].def = jpeg_qual[sd->reg08]; 6621 + sd->ctrls[QUALITY].min = jpeg_qual[0]; 6622 + sd->ctrls[QUALITY].max = jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1]; 6734 6623 6735 6624 switch (sd->sensor) { 6736 6625 case SENSOR_HV7131R: 6626 + gspca_dev->ctrl_dis = (1 << QUALITY); 6737 6627 break; 6738 6628 case SENSOR_OV7630C: 6739 6629 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE); 6630 + break; 6631 + case SENSOR_PAS202B: 6632 + gspca_dev->ctrl_dis = (1 << QUALITY) | (1 << EXPOSURE); 6740 6633 break; 6741 6634 default: 6742 6635 gspca_dev->ctrl_dis = (1 << EXPOSURE); ··· 6808 6685 /* create the JPEG header */ 6809 6686 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 6810 6687 0x21); /* JPEG 422 */ 6811 - jpeg_set_qual(sd->jpeg_hdr, sd->quality); 6812 6688 6813 6689 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 6814 6690 switch (sd->sensor) { ··· 6883 6761 reg_r(gspca_dev, 0x0180); /* from win */ 6884 6762 reg_w(gspca_dev, 0x00, 0x0180); 6885 6763 break; 6886 - default: 6887 - setquality(gspca_dev); 6888 - break; 6889 6764 } 6765 + setquality(gspca_dev); 6766 + jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08]); 6890 6767 setlightfreq(gspca_dev); 6891 6768 6892 6769 switch (sd->sensor) { ··· 6897 6776 reg_w(gspca_dev, 0x40, 0x0117); 6898 6777 break; 6899 6778 case SENSOR_HV7131R: 6900 - if (!sd->ctrls[AUTOGAIN].val) 6901 - setexposure(gspca_dev); 6779 + setexposure(gspca_dev); 6902 6780 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); 6903 6781 break; 6904 6782 case SENSOR_GC0305: ··· 6922 6802 } 6923 6803 6924 6804 setautogain(gspca_dev); 6925 - switch (sd->sensor) { 6926 - case SENSOR_PO2030: 6927 - msleep(50); 6928 - reg_w(gspca_dev, 0x00, 0x0007); /* (from win traces) */ 6929 - reg_w(gspca_dev, 0x02, ZC3XX_R008_CLOCKSETTING); 6930 - break; 6805 + 6806 + /* start the transfer update thread if needed */ 6807 + if (gspca_dev->usb_err >= 0) { 6808 + switch (sd->sensor) { 6809 + case SENSOR_HV7131R: 6810 + case SENSOR_PAS202B: 6811 + sd->work_thread = 6812 + create_singlethread_workqueue(KBUILD_MODNAME); 6813 + queue_work(sd->work_thread, &sd->work); 6814 + break; 6815 + } 6931 6816 } 6817 + 6932 6818 return gspca_dev->usb_err; 6933 6819 } 6934 6820 ··· 6943 6817 { 6944 6818 struct sd *sd = (struct sd *) gspca_dev; 6945 6819 6820 + if (sd->work_thread != NULL) { 6821 + mutex_unlock(&gspca_dev->usb_lock); 6822 + destroy_workqueue(sd->work_thread); 6823 + mutex_lock(&gspca_dev->usb_lock); 6824 + sd->work_thread = NULL; 6825 + } 6946 6826 if (!gspca_dev->present) 6947 6827 return; 6948 6828 send_unknown(gspca_dev, sd->sensor); ··· 7025 6893 return -EINVAL; 7026 6894 } 7027 6895 6896 + static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val) 6897 + { 6898 + struct sd *sd = (struct sd *) gspca_dev; 6899 + int i; 6900 + 6901 + for (i = 0; i < ARRAY_SIZE(jpeg_qual) - 1; i++) { 6902 + if (val <= jpeg_qual[i]) 6903 + break; 6904 + } 6905 + if (i > 0 6906 + && i == sd->reg08 6907 + && val < jpeg_qual[sd->reg08]) 6908 + i--; 6909 + sd->reg08 = i; 6910 + sd->ctrls[QUALITY].val = jpeg_qual[i]; 6911 + if (gspca_dev->streaming) 6912 + jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val); 6913 + return gspca_dev->usb_err; 6914 + } 6915 + 7028 6916 static int sd_set_jcomp(struct gspca_dev *gspca_dev, 7029 6917 struct v4l2_jpegcompression *jcomp) 7030 6918 { 7031 6919 struct sd *sd = (struct sd *) gspca_dev; 7032 6920 7033 - if (jcomp->quality < QUALITY_MIN) 7034 - sd->quality = QUALITY_MIN; 7035 - else if (jcomp->quality > QUALITY_MAX) 7036 - sd->quality = QUALITY_MAX; 7037 - else 7038 - sd->quality = jcomp->quality; 7039 - if (gspca_dev->streaming) 7040 - jpeg_set_qual(sd->jpeg_hdr, sd->quality); 6921 + sd_setquality(gspca_dev, jcomp->quality); 6922 + jcomp->quality = sd->ctrls[QUALITY].val; 7041 6923 return gspca_dev->usb_err; 7042 6924 } 7043 6925 ··· 7061 6915 struct sd *sd = (struct sd *) gspca_dev; 7062 6916 7063 6917 memset(jcomp, 0, sizeof *jcomp); 7064 - jcomp->quality = sd->quality; 6918 + jcomp->quality = sd->ctrls[QUALITY].val; 7065 6919 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 7066 6920 | V4L2_JPEG_MARKER_DQT; 7067 6921 return 0; ··· 7084 6938 #endif 7085 6939 7086 6940 static const struct sd_desc sd_desc = { 7087 - .name = MODULE_NAME, 6941 + .name = KBUILD_MODNAME, 7088 6942 .ctrls = sd_ctrls, 7089 6943 .nctrls = ARRAY_SIZE(sd_ctrls), 7090 6944 .config = sd_config, ··· 7169 7023 7170 7024 /* USB driver */ 7171 7025 static struct usb_driver sd_driver = { 7172 - .name = MODULE_NAME, 7026 + .name = KBUILD_MODNAME, 7173 7027 .id_table = device_table, 7174 7028 .probe = sd_probe, 7175 7029 .disconnect = gspca_disconnect,
+1 -12
drivers/media/video/imx074.c
··· 468 468 .id_table = imx074_id, 469 469 }; 470 470 471 - static int __init imx074_mod_init(void) 472 - { 473 - return i2c_add_driver(&imx074_i2c_driver); 474 - } 475 - 476 - static void __exit imx074_mod_exit(void) 477 - { 478 - i2c_del_driver(&imx074_i2c_driver); 479 - } 480 - 481 - module_init(imx074_mod_init); 482 - module_exit(imx074_mod_exit); 471 + module_i2c_driver(imx074_i2c_driver); 483 472 484 473 MODULE_DESCRIPTION("Sony IMX074 Camera driver"); 485 474 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+1 -12
drivers/media/video/indycam.c
··· 387 387 .id_table = indycam_id, 388 388 }; 389 389 390 - static __init int init_indycam(void) 391 - { 392 - return i2c_add_driver(&indycam_driver); 393 - } 394 - 395 - static __exit void exit_indycam(void) 396 - { 397 - i2c_del_driver(&indycam_driver); 398 - } 399 - 400 - module_init(init_indycam); 401 - module_exit(exit_indycam); 390 + module_i2c_driver(indycam_driver);
+3 -14
drivers/media/video/ir-kbd-i2c.c
··· 471 471 { } 472 472 }; 473 473 474 - static struct i2c_driver driver = { 474 + static struct i2c_driver ir_kbd_driver = { 475 475 .driver = { 476 476 .name = "ir-kbd-i2c", 477 477 }, ··· 480 480 .id_table = ir_kbd_id, 481 481 }; 482 482 483 + module_i2c_driver(ir_kbd_driver); 484 + 483 485 /* ----------------------------------------------------------------------- */ 484 486 485 487 MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller"); 486 488 MODULE_DESCRIPTION("input driver for i2c IR remote controls"); 487 489 MODULE_LICENSE("GPL"); 488 - 489 - static int __init ir_init(void) 490 - { 491 - return i2c_add_driver(&driver); 492 - } 493 - 494 - static void __exit ir_fini(void) 495 - { 496 - i2c_del_driver(&driver); 497 - } 498 - 499 - module_init(ir_init); 500 - module_exit(ir_fini);
+4 -4
drivers/media/video/ivtv/Makefile
··· 7 7 obj-$(CONFIG_VIDEO_IVTV) += ivtv.o 8 8 obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o 9 9 10 - ccflags-y += -Idrivers/media/video 11 - ccflags-y += -Idrivers/media/common/tuners 12 - ccflags-y += -Idrivers/media/dvb/dvb-core 13 - ccflags-y += -Idrivers/media/dvb/frontends 10 + ccflags-y += -I$(srctree)/drivers/media/video 11 + ccflags-y += -I$(srctree)/drivers/media/common/tuners 12 + ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core 13 + ccflags-y += -I$(srctree)/drivers/media/dvb/frontends 14 14
+62
drivers/media/video/ivtv/ivtv-controls.c
··· 21 21 #include "ivtv-driver.h" 22 22 #include "ivtv-ioctl.h" 23 23 #include "ivtv-controls.h" 24 + #include "ivtv-mailbox.h" 24 25 25 26 static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt) 26 27 { ··· 99 98 .s_audio_sampling_freq = ivtv_s_audio_sampling_freq, 100 99 .s_video_encoding = ivtv_s_video_encoding, 101 100 .s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt, 101 + }; 102 + 103 + int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame) 104 + { 105 + u32 data[CX2341X_MBOX_MAX_DATA]; 106 + 107 + if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) { 108 + *pts = (s64)((u64)itv->last_dec_timing[2] << 32) | 109 + (u64)itv->last_dec_timing[1]; 110 + *frame = itv->last_dec_timing[0]; 111 + return 0; 112 + } 113 + *pts = 0; 114 + *frame = 0; 115 + if (atomic_read(&itv->decoding)) { 116 + if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) { 117 + IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n"); 118 + return -EIO; 119 + } 120 + memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing)); 121 + set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags); 122 + *pts = (s64)((u64) data[2] << 32) | (u64) data[1]; 123 + *frame = data[0]; 124 + /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/ 125 + } 126 + return 0; 127 + } 128 + 129 + static int ivtv_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 130 + { 131 + struct ivtv *itv = container_of(ctrl->handler, struct ivtv, cxhdl.hdl); 132 + 133 + switch (ctrl->id) { 134 + /* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME 135 + control cluster */ 136 + case V4L2_CID_MPEG_VIDEO_DEC_PTS: 137 + return ivtv_g_pts_frame(itv, &itv->ctrl_pts->val64, 138 + &itv->ctrl_frame->val64); 139 + } 140 + return 0; 141 + } 142 + 143 + static int ivtv_s_ctrl(struct v4l2_ctrl *ctrl) 144 + { 145 + struct ivtv *itv = container_of(ctrl->handler, struct ivtv, cxhdl.hdl); 146 + 147 + switch (ctrl->id) { 148 + /* V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK and MULTILINGUAL_PLAYBACK 149 + control cluster */ 150 + case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: 151 + itv->audio_stereo_mode = itv->ctrl_audio_playback->val - 1; 152 + itv->audio_bilingual_mode = itv->ctrl_audio_multilingual_playback->val - 1; 153 + ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); 154 + break; 155 + } 156 + return 0; 157 + } 158 + 159 + const struct v4l2_ctrl_ops ivtv_hdl_out_ops = { 160 + .s_ctrl = ivtv_s_ctrl, 161 + .g_volatile_ctrl = ivtv_g_volatile_ctrl, 102 162 };
+2
drivers/media/video/ivtv/ivtv-controls.h
··· 22 22 #define IVTV_CONTROLS_H 23 23 24 24 extern struct cx2341x_handler_ops ivtv_cxhdl_ops; 25 + extern const struct v4l2_ctrl_ops ivtv_hdl_out_ops; 26 + int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame); 25 27 26 28 #endif
+34 -7
drivers/media/video/ivtv/ivtv-driver.c
··· 55 55 #include "ivtv-routing.h" 56 56 #include "ivtv-controls.h" 57 57 #include "ivtv-gpio.h" 58 - 58 + #include <linux/dma-mapping.h> 59 59 #include <media/tveeprom.h> 60 60 #include <media/saa7115.h> 61 61 #include <media/v4l2-chip-ident.h> ··· 99 99 100 100 static unsigned int cardtype_c = 1; 101 101 static unsigned int tuner_c = 1; 102 - static bool radio_c = 1; 102 + static int radio_c = 1; 103 103 static unsigned int i2c_clock_period_c = 1; 104 104 static char pal[] = "---"; 105 105 static char secam[] = "--"; ··· 139 139 static int newi2c = -1; 140 140 141 141 module_param_array(tuner, int, &tuner_c, 0644); 142 - module_param_array(radio, bool, &radio_c, 0644); 142 + module_param_array(radio, int, &radio_c, 0644); 143 143 module_param_array(cardtype, int, &cardtype_c, 0644); 144 144 module_param_string(pal, pal, sizeof(pal), 0644); 145 145 module_param_string(secam, secam, sizeof(secam), 0644); ··· 744 744 745 745 itv->cur_dma_stream = -1; 746 746 itv->cur_pio_stream = -1; 747 - itv->audio_stereo_mode = AUDIO_STEREO; 748 - itv->audio_bilingual_mode = AUDIO_MONO_LEFT; 749 747 750 748 /* Ctrls */ 751 749 itv->speed = 1000; ··· 813 815 IVTV_ERR("Can't enable device!\n"); 814 816 return -EIO; 815 817 } 816 - if (pci_set_dma_mask(pdev, 0xffffffff)) { 818 + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { 817 819 IVTV_ERR("No suitable DMA available.\n"); 818 820 return -EIO; 819 821 } ··· 1198 1200 itv->tuner_std = itv->std; 1199 1201 1200 1202 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { 1203 + struct v4l2_ctrl_handler *hdl = itv->v4l2_dev.ctrl_handler; 1204 + 1205 + itv->ctrl_pts = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops, 1206 + V4L2_CID_MPEG_VIDEO_DEC_PTS, 0, 0, 1, 0); 1207 + itv->ctrl_frame = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops, 1208 + V4L2_CID_MPEG_VIDEO_DEC_FRAME, 0, 0x7fffffff, 1, 0); 1209 + /* Note: V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO is not supported, 1210 + mask that menu item. */ 1211 + itv->ctrl_audio_playback = 1212 + v4l2_ctrl_new_std_menu(hdl, &ivtv_hdl_out_ops, 1213 + V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK, 1214 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO, 1215 + 1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO, 1216 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO); 1217 + itv->ctrl_audio_multilingual_playback = 1218 + v4l2_ctrl_new_std_menu(hdl, &ivtv_hdl_out_ops, 1219 + V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK, 1220 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO, 1221 + 1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO, 1222 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT); 1223 + if (hdl->error) { 1224 + retval = hdl->error; 1225 + goto free_i2c; 1226 + } 1227 + v4l2_ctrl_cluster(2, &itv->ctrl_pts); 1228 + v4l2_ctrl_cluster(2, &itv->ctrl_audio_playback); 1201 1229 ivtv_call_all(itv, video, s_std_output, itv->std); 1202 1230 /* Turn off the output signal. The mpeg decoder is not yet 1203 1231 active so without this you would get a green image until the ··· 1260 1236 free_irq: 1261 1237 free_irq(itv->pdev->irq, (void *)itv); 1262 1238 free_i2c: 1239 + v4l2_ctrl_handler_free(&itv->cxhdl.hdl); 1263 1240 exit_ivtv_i2c(itv); 1264 1241 free_io: 1265 1242 ivtv_iounmap(itv); ··· 1400 1375 else 1401 1376 type = IVTV_DEC_STREAM_TYPE_MPG; 1402 1377 ivtv_stop_v4l2_decode_stream(&itv->streams[type], 1403 - VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); 1378 + V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0); 1404 1379 } 1405 1380 ivtv_halt_firmware(itv); 1406 1381 } ··· 1415 1390 1416 1391 ivtv_streams_cleanup(itv, 1); 1417 1392 ivtv_udma_free(itv); 1393 + 1394 + v4l2_ctrl_handler_free(&itv->cxhdl.hdl); 1418 1395 1419 1396 exit_ivtv_i2c(itv); 1420 1397
+11 -1
drivers/media/video/ivtv/ivtv-driver.h
··· 331 331 struct ivtv *itv; /* for ease of use */ 332 332 const char *name; /* name of the stream */ 333 333 int type; /* stream type */ 334 + u32 caps; /* V4L2 capabilities */ 334 335 335 336 struct v4l2_fh *fh; /* pointer to the streaming filehandle */ 336 337 spinlock_t qlock; /* locks access to the queues */ ··· 631 630 632 631 struct v4l2_device v4l2_dev; 633 632 struct cx2341x_handler cxhdl; 633 + struct { 634 + /* PTS/Frame count control cluster */ 635 + struct v4l2_ctrl *ctrl_pts; 636 + struct v4l2_ctrl *ctrl_frame; 637 + }; 638 + struct { 639 + /* Audio Playback control cluster */ 640 + struct v4l2_ctrl *ctrl_audio_playback; 641 + struct v4l2_ctrl *ctrl_audio_multilingual_playback; 642 + }; 634 643 struct v4l2_ctrl_handler hdl_gpio; 635 644 struct v4l2_subdev sd_gpio; /* GPIO sub-device */ 636 645 u16 instance; ··· 659 648 v4l2_std_id std_out; /* current TV output standard */ 660 649 u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */ 661 650 u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */ 662 - 663 651 664 652 /* Locking */ 665 653 spinlock_t lock; /* lock access to this struct */
+1 -1
drivers/media/video/ivtv/ivtv-fileops.c
··· 900 900 if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { 901 901 struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; 902 902 903 - ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); 903 + ivtv_stop_decoding(id, V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0); 904 904 905 905 /* If all output streams are closed, and if the user doesn't have 906 906 IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */
+88 -100
drivers/media/video/ivtv/ivtv-ioctl.c
··· 246 246 } 247 247 248 248 static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, 249 - struct video_command *vc, int try) 249 + struct v4l2_decoder_cmd *dc, int try) 250 250 { 251 251 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; 252 252 253 253 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 254 254 return -EINVAL; 255 255 256 - switch (vc->cmd) { 257 - case VIDEO_CMD_PLAY: { 258 - vc->flags = 0; 259 - vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed); 260 - if (vc->play.speed < 0) 261 - vc->play.format = VIDEO_PLAY_FMT_GOP; 256 + switch (dc->cmd) { 257 + case V4L2_DEC_CMD_START: { 258 + dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO; 259 + dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed); 260 + if (dc->start.speed < 0) 261 + dc->start.format = V4L2_DEC_START_FMT_GOP; 262 + else 263 + dc->start.format = V4L2_DEC_START_FMT_NONE; 264 + if (dc->start.speed != 500 && dc->start.speed != 1500) 265 + dc->flags = dc->start.speed == 1000 ? 0 : 266 + V4L2_DEC_CMD_START_MUTE_AUDIO; 262 267 if (try) break; 263 268 269 + itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO; 264 270 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG) 265 271 return -EBUSY; 266 272 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { 267 273 /* forces ivtv_set_speed to be called */ 268 274 itv->speed = 0; 269 275 } 270 - return ivtv_start_decoding(id, vc->play.speed); 276 + return ivtv_start_decoding(id, dc->start.speed); 271 277 } 272 278 273 - case VIDEO_CMD_STOP: 274 - vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK; 275 - if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY) 276 - vc->stop.pts = 0; 279 + case V4L2_DEC_CMD_STOP: 280 + dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK; 281 + if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) 282 + dc->stop.pts = 0; 277 283 if (try) break; 278 284 if (atomic_read(&itv->decoding) == 0) 279 285 return 0; ··· 287 281 return -EBUSY; 288 282 289 283 itv->output_mode = OUT_NONE; 290 - return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts); 284 + return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts); 291 285 292 - case VIDEO_CMD_FREEZE: 293 - vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK; 286 + case V4L2_DEC_CMD_PAUSE: 287 + dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK; 294 288 if (try) break; 295 289 if (itv->output_mode != OUT_MPG) 296 290 return -EBUSY; 297 291 if (atomic_read(&itv->decoding) > 0) { 298 292 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 299 - (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0); 293 + (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0); 300 294 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); 301 295 } 302 296 break; 303 297 304 - case VIDEO_CMD_CONTINUE: 305 - vc->flags = 0; 298 + case V4L2_DEC_CMD_RESUME: 299 + dc->flags = 0; 306 300 if (try) break; 307 301 if (itv->output_mode != OUT_MPG) 308 302 return -EBUSY; ··· 760 754 761 755 static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) 762 756 { 763 - struct ivtv *itv = fh2id(fh)->itv; 757 + struct ivtv_open_id *id = fh2id(file->private_data); 758 + struct ivtv *itv = id->itv; 759 + struct ivtv_stream *s = &itv->streams[id->type]; 764 760 765 761 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); 766 762 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); 767 763 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); 768 - vcap->capabilities = itv->v4l2_cap; /* capabilities */ 764 + vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS; 765 + vcap->device_caps = s->caps; 769 766 return 0; 770 767 } 771 768 ··· 1485 1476 struct v4l2_audio audin; 1486 1477 int i; 1487 1478 1488 - IVTV_INFO("================= START STATUS CARD #%d =================\n", 1489 - itv->instance); 1490 1479 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); 1491 1480 if (itv->hw_flags & IVTV_HW_TVEEPROM) { 1492 1481 struct tveeprom tv; ··· 1507 1500 "YUV Streaming", 1508 1501 "YUV Frames", 1509 1502 "Passthrough", 1510 - }; 1511 - static const char * const audio_modes[5] = { 1512 - "Stereo", 1513 - "Left", 1514 - "Right", 1515 - "Mono", 1516 - "Swapped" 1517 1503 }; 1518 1504 static const char * const alpha_mode[4] = { 1519 1505 "None", ··· 1536 1536 ivtv_get_output(itv, itv->active_output, &vidout); 1537 1537 ivtv_get_audio_output(itv, 0, &audout); 1538 1538 IVTV_INFO("Video Output: %s\n", vidout.name); 1539 - IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name, 1540 - audio_modes[itv->audio_stereo_mode], 1541 - audio_modes[itv->audio_bilingual_mode]); 1542 1539 if (mode < 0 || mode > OUT_PASSTHROUGH) 1543 1540 mode = OUT_NONE; 1544 1541 IVTV_INFO("Output Mode: %s\n", output_modes[mode]); ··· 1563 1566 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", 1564 1567 (long long)itv->mpg_data_received, 1565 1568 (long long)itv->vbi_data_inserted); 1566 - IVTV_INFO("================== END STATUS CARD #%d ==================\n", 1567 - itv->instance); 1568 - 1569 1569 return 0; 1570 + } 1571 + 1572 + static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec) 1573 + { 1574 + struct ivtv_open_id *id = fh2id(file->private_data); 1575 + struct ivtv *itv = id->itv; 1576 + 1577 + IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd); 1578 + return ivtv_video_command(itv, id, dec, false); 1579 + } 1580 + 1581 + static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec) 1582 + { 1583 + struct ivtv_open_id *id = fh2id(file->private_data); 1584 + struct ivtv *itv = id->itv; 1585 + 1586 + IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd); 1587 + return ivtv_video_command(itv, id, dec, true); 1570 1588 } 1571 1589 1572 1590 static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) ··· 1617 1605 return ivtv_yuv_prep_frame(itv, args); 1618 1606 } 1619 1607 1608 + case IVTV_IOC_PASSTHROUGH_MODE: 1609 + IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n"); 1610 + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 1611 + return -EINVAL; 1612 + return ivtv_passthrough_mode(itv, *(int *)arg != 0); 1613 + 1620 1614 case VIDEO_GET_PTS: { 1621 - u32 data[CX2341X_MBOX_MAX_DATA]; 1622 - u64 *pts = arg; 1615 + s64 *pts = arg; 1616 + s64 frame; 1623 1617 1624 1618 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n"); 1625 1619 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) { ··· 1634 1616 } 1635 1617 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 1636 1618 return -EINVAL; 1637 - 1638 - if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) { 1639 - *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) | 1640 - (u64)itv->last_dec_timing[1]; 1641 - break; 1642 - } 1643 - *pts = 0; 1644 - if (atomic_read(&itv->decoding)) { 1645 - if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) { 1646 - IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n"); 1647 - return -EIO; 1648 - } 1649 - memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing)); 1650 - set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags); 1651 - *pts = (u64) ((u64) data[2] << 32) | (u64) data[1]; 1652 - /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/ 1653 - } 1654 - break; 1619 + return ivtv_g_pts_frame(itv, pts, &frame); 1655 1620 } 1656 1621 1657 1622 case VIDEO_GET_FRAME_COUNT: { 1658 - u32 data[CX2341X_MBOX_MAX_DATA]; 1659 - u64 *frame = arg; 1623 + s64 *frame = arg; 1624 + s64 pts; 1660 1625 1661 1626 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n"); 1662 1627 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) { ··· 1648 1647 } 1649 1648 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 1650 1649 return -EINVAL; 1651 - 1652 - if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) { 1653 - *frame = itv->last_dec_timing[0]; 1654 - break; 1655 - } 1656 - *frame = 0; 1657 - if (atomic_read(&itv->decoding)) { 1658 - if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) { 1659 - IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n"); 1660 - return -EIO; 1661 - } 1662 - memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing)); 1663 - set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags); 1664 - *frame = data[0]; 1665 - } 1666 - break; 1650 + return ivtv_g_pts_frame(itv, &pts, frame); 1667 1651 } 1668 1652 1669 1653 case VIDEO_PLAY: { 1670 - struct video_command vc; 1654 + struct v4l2_decoder_cmd dc; 1671 1655 1672 1656 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n"); 1673 - memset(&vc, 0, sizeof(vc)); 1674 - vc.cmd = VIDEO_CMD_PLAY; 1675 - return ivtv_video_command(itv, id, &vc, 0); 1657 + memset(&dc, 0, sizeof(dc)); 1658 + dc.cmd = V4L2_DEC_CMD_START; 1659 + return ivtv_video_command(itv, id, &dc, 0); 1676 1660 } 1677 1661 1678 1662 case VIDEO_STOP: { 1679 - struct video_command vc; 1663 + struct v4l2_decoder_cmd dc; 1680 1664 1681 1665 IVTV_DEBUG_IOCTL("VIDEO_STOP\n"); 1682 - memset(&vc, 0, sizeof(vc)); 1683 - vc.cmd = VIDEO_CMD_STOP; 1684 - vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY; 1685 - return ivtv_video_command(itv, id, &vc, 0); 1666 + memset(&dc, 0, sizeof(dc)); 1667 + dc.cmd = V4L2_DEC_CMD_STOP; 1668 + dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY; 1669 + return ivtv_video_command(itv, id, &dc, 0); 1686 1670 } 1687 1671 1688 1672 case VIDEO_FREEZE: { 1689 - struct video_command vc; 1673 + struct v4l2_decoder_cmd dc; 1690 1674 1691 1675 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n"); 1692 - memset(&vc, 0, sizeof(vc)); 1693 - vc.cmd = VIDEO_CMD_FREEZE; 1694 - return ivtv_video_command(itv, id, &vc, 0); 1676 + memset(&dc, 0, sizeof(dc)); 1677 + dc.cmd = V4L2_DEC_CMD_PAUSE; 1678 + return ivtv_video_command(itv, id, &dc, 0); 1695 1679 } 1696 1680 1697 1681 case VIDEO_CONTINUE: { 1698 - struct video_command vc; 1682 + struct v4l2_decoder_cmd dc; 1699 1683 1700 1684 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n"); 1701 - memset(&vc, 0, sizeof(vc)); 1702 - vc.cmd = VIDEO_CMD_CONTINUE; 1703 - return ivtv_video_command(itv, id, &vc, 0); 1685 + memset(&dc, 0, sizeof(dc)); 1686 + dc.cmd = V4L2_DEC_CMD_RESUME; 1687 + return ivtv_video_command(itv, id, &dc, 0); 1704 1688 } 1705 1689 1706 1690 case VIDEO_COMMAND: 1707 1691 case VIDEO_TRY_COMMAND: { 1708 - struct video_command *vc = arg; 1692 + /* Note: struct v4l2_decoder_cmd has the same layout as 1693 + struct video_command */ 1694 + struct v4l2_decoder_cmd *dc = arg; 1709 1695 int try = (cmd == VIDEO_TRY_COMMAND); 1710 1696 1711 1697 if (try) 1712 - IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd); 1698 + IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd); 1713 1699 else 1714 - IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd); 1715 - return ivtv_video_command(itv, id, vc, try); 1700 + IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd); 1701 + return ivtv_video_command(itv, id, dc, try); 1716 1702 } 1717 1703 1718 1704 case VIDEO_GET_EVENT: { ··· 1763 1775 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); 1764 1776 if (iarg > AUDIO_STEREO_SWAPPED) 1765 1777 return -EINVAL; 1766 - itv->audio_stereo_mode = iarg; 1767 - ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); 1768 - return 0; 1778 + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg); 1769 1779 1770 1780 case AUDIO_BILINGUAL_CHANNEL_SELECT: 1771 1781 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); 1772 1782 if (iarg > AUDIO_STEREO_SWAPPED) 1773 1783 return -EINVAL; 1774 - itv->audio_bilingual_mode = iarg; 1775 - ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); 1776 - return 0; 1784 + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg); 1777 1785 1778 1786 default: 1779 1787 return -EINVAL; ··· 1784 1800 1785 1801 if (!valid_prio) { 1786 1802 switch (cmd) { 1803 + case IVTV_IOC_PASSTHROUGH_MODE: 1787 1804 case VIDEO_PLAY: 1788 1805 case VIDEO_STOP: 1789 1806 case VIDEO_FREEZE: ··· 1810 1825 } 1811 1826 1812 1827 case IVTV_IOC_DMA_FRAME: 1828 + case IVTV_IOC_PASSTHROUGH_MODE: 1813 1829 case VIDEO_GET_PTS: 1814 1830 case VIDEO_GET_FRAME_COUNT: 1815 1831 case VIDEO_GET_EVENT: ··· 1875 1889 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap, 1876 1890 .vidioc_encoder_cmd = ivtv_encoder_cmd, 1877 1891 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd, 1892 + .vidioc_decoder_cmd = ivtv_decoder_cmd, 1893 + .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd, 1878 1894 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out, 1879 1895 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap, 1880 1896 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
+17 -3
drivers/media/video/ivtv/ivtv-streams.c
··· 78 78 int num_offset; 79 79 int dma, pio; 80 80 enum v4l2_buf_type buf_type; 81 + u32 v4l2_caps; 81 82 const struct v4l2_file_operations *fops; 82 83 } ivtv_stream_info[] = { 83 84 { /* IVTV_ENC_STREAM_TYPE_MPG */ 84 85 "encoder MPG", 85 86 VFL_TYPE_GRABBER, 0, 86 87 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 88 + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | 89 + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, 87 90 &ivtv_v4l2_enc_fops 88 91 }, 89 92 { /* IVTV_ENC_STREAM_TYPE_YUV */ 90 93 "encoder YUV", 91 94 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET, 92 95 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 96 + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | 97 + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, 93 98 &ivtv_v4l2_enc_fops 94 99 }, 95 100 { /* IVTV_ENC_STREAM_TYPE_VBI */ 96 101 "encoder VBI", 97 102 VFL_TYPE_VBI, 0, 98 103 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE, 104 + V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_TUNER | 105 + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, 99 106 &ivtv_v4l2_enc_fops 100 107 }, 101 108 { /* IVTV_ENC_STREAM_TYPE_PCM */ 102 109 "encoder PCM", 103 110 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET, 104 111 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE, 112 + V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, 105 113 &ivtv_v4l2_enc_fops 106 114 }, 107 115 { /* IVTV_ENC_STREAM_TYPE_RAD */ 108 116 "encoder radio", 109 117 VFL_TYPE_RADIO, 0, 110 118 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE, 119 + V4L2_CAP_RADIO | V4L2_CAP_TUNER, 111 120 &ivtv_v4l2_enc_fops 112 121 }, 113 122 { /* IVTV_DEC_STREAM_TYPE_MPG */ 114 123 "decoder MPG", 115 124 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET, 116 125 PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, 126 + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, 117 127 &ivtv_v4l2_dec_fops 118 128 }, 119 129 { /* IVTV_DEC_STREAM_TYPE_VBI */ 120 130 "decoder VBI", 121 131 VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET, 122 132 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE, 133 + V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_READWRITE, 123 134 &ivtv_v4l2_enc_fops 124 135 }, 125 136 { /* IVTV_DEC_STREAM_TYPE_VOUT */ 126 137 "decoder VOUT", 127 138 VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET, 128 139 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT, 140 + V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, 129 141 &ivtv_v4l2_dec_fops 130 142 }, 131 143 { /* IVTV_DEC_STREAM_TYPE_YUV */ 132 144 "decoder YUV", 133 145 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET, 134 146 PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, 147 + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, 135 148 &ivtv_v4l2_dec_fops 136 149 } 137 150 }; ··· 162 149 s->itv = itv; 163 150 s->type = type; 164 151 s->name = ivtv_stream_info[type].name; 152 + s->caps = ivtv_stream_info[type].v4l2_caps; 165 153 166 154 if (ivtv_stream_info[type].pio) 167 155 s->dma = PCI_DMA_NONE; ··· 223 209 224 210 s->vdev->num = num; 225 211 s->vdev->v4l2_dev = &itv->v4l2_dev; 226 - s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler; 227 212 s->vdev->fops = ivtv_stream_info[type].fops; 213 + s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler; 228 214 s->vdev->release = video_device_release; 229 215 s->vdev->tvnorms = V4L2_STD_ALL; 230 216 s->vdev->lock = &itv->serialize_lock; ··· 905 891 IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags); 906 892 907 893 /* Stop Decoder */ 908 - if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) { 894 + if (!(flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) || pts) { 909 895 u32 tmp = 0; 910 896 911 897 /* Wait until the decoder is no longer running */ ··· 925 911 break; 926 912 } 927 913 } 928 - ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & VIDEO_CMD_STOP_TO_BLACK, 0, 0); 914 + ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & V4L2_DEC_CMD_STOP_TO_BLACK, 0, 0); 929 915 930 916 /* turn off notification of dual/stereo mode change */ 931 917 ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
+1 -12
drivers/media/video/ks0127.c
··· 721 721 .id_table = ks0127_id, 722 722 }; 723 723 724 - static __init int init_ks0127(void) 725 - { 726 - return i2c_add_driver(&ks0127_driver); 727 - } 728 - 729 - static __exit void exit_ks0127(void) 730 - { 731 - i2c_del_driver(&ks0127_driver); 732 - } 733 - 734 - module_init(init_ks0127); 735 - module_exit(exit_ks0127); 724 + module_i2c_driver(ks0127_driver);
+1 -12
drivers/media/video/m52790.c
··· 213 213 .id_table = m52790_id, 214 214 }; 215 215 216 - static __init int init_m52790(void) 217 - { 218 - return i2c_add_driver(&m52790_driver); 219 - } 220 - 221 - static __exit void exit_m52790(void) 222 - { 223 - i2c_del_driver(&m52790_driver); 224 - } 225 - 226 - module_init(init_m52790); 227 - module_exit(exit_m52790); 216 + module_i2c_driver(m52790_driver);
+2 -13
drivers/media/video/m5mols/m5mols_core.c
··· 982 982 } 983 983 984 984 sd = &info->sd; 985 - strlcpy(sd->name, MODULE_NAME, sizeof(sd->name)); 986 985 v4l2_i2c_subdev_init(sd, client, &m5mols_ops); 986 + strlcpy(sd->name, MODULE_NAME, sizeof(sd->name)); 987 987 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 988 988 989 989 sd->internal_ops = &m5mols_subdev_internal_ops; ··· 1057 1057 .id_table = m5mols_id, 1058 1058 }; 1059 1059 1060 - static int __init m5mols_mod_init(void) 1061 - { 1062 - return i2c_add_driver(&m5mols_i2c_driver); 1063 - } 1064 - 1065 - static void __exit m5mols_mod_exit(void) 1066 - { 1067 - i2c_del_driver(&m5mols_i2c_driver); 1068 - } 1069 - 1070 - module_init(m5mols_mod_init); 1071 - module_exit(m5mols_mod_exit); 1060 + module_i2c_driver(m5mols_i2c_driver); 1072 1061 1073 1062 MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>"); 1074 1063 MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>");
+23 -12
drivers/media/video/marvell-ccic/mcam-core.c
··· 509 509 510 510 buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue); 511 511 list_del_init(&buf->queue); 512 + /* 513 + * Very Bad Not Good Things happen if you don't clear 514 + * C1_DESC_ENA before making any descriptor changes. 515 + */ 516 + mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA); 512 517 mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa); 513 518 mcam_reg_write(cam, REG_DESC_LEN_Y, 514 519 buf->dma_desc_nent*sizeof(struct mcam_dma_desc)); 515 520 mcam_reg_write(cam, REG_DESC_LEN_U, 0); 516 521 mcam_reg_write(cam, REG_DESC_LEN_V, 0); 522 + mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA); 517 523 cam->vb_bufs[0] = buf; 518 524 } 519 525 ··· 539 533 540 534 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_3WORD); 541 535 mcam_sg_next_buffer(cam); 542 - mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA); 543 536 cam->nbufs = 3; 544 537 } 545 538 ··· 561 556 struct mcam_vb_buffer *buf = cam->vb_bufs[0]; 562 557 563 558 /* 564 - * Very Bad Not Good Things happen if you don't clear 565 - * C1_DESC_ENA before making any descriptor changes. 559 + * If we're no longer supposed to be streaming, don't do anything. 566 560 */ 567 - mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA); 561 + if (cam->state != S_STREAMING) 562 + return; 568 563 /* 569 564 * If we have another buffer available, put it in and 570 565 * restart the engine. 571 566 */ 572 567 if (!list_empty(&cam->buffers)) { 573 568 mcam_sg_next_buffer(cam); 574 - mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA); 575 569 mcam_ctlr_start(cam); 576 570 /* 577 571 * Otherwise set CF_SG_RESTART and the controller will ··· 741 737 mcam_ctlr_stop(cam); 742 738 cam->state = S_IDLE; 743 739 spin_unlock_irqrestore(&cam->dev_lock, flags); 744 - msleep(40); 740 + /* 741 + * This is a brutally long sleep, but experience shows that 742 + * it can take the controller a while to get the message that 743 + * it needs to stop grabbing frames. In particular, we can 744 + * sometimes (on mmp) get a frame at the end WITHOUT the 745 + * start-of-frame indication. 746 + */ 747 + msleep(150); 745 748 if (test_bit(CF_DMA_ACTIVE, &cam->flags)) 746 749 cam_err(cam, "Timeout waiting for DMA to end\n"); 747 750 /* This would be bad news - what now? */ ··· 891 880 * Turn it loose. 892 881 */ 893 882 spin_lock_irqsave(&cam->dev_lock, flags); 883 + clear_bit(CF_DMA_ACTIVE, &cam->flags); 894 884 mcam_reset_buffers(cam); 895 885 mcam_ctlr_irq_enable(cam); 896 886 cam->state = S_STREAMING; ··· 934 922 spin_lock_irqsave(&cam->dev_lock, flags); 935 923 start = (cam->state == S_BUFWAIT) && !list_empty(&cam->buffers); 936 924 list_add(&mvb->queue, &cam->buffers); 937 - if (test_bit(CF_SG_RESTART, &cam->flags)) 925 + if (cam->state == S_STREAMING && test_bit(CF_SG_RESTART, &cam->flags)) 938 926 mcam_sg_restart(cam); 939 927 spin_unlock_irqrestore(&cam->dev_lock, flags); 940 928 if (start) ··· 1567 1555 { 1568 1556 struct mcam_camera *cam = filp->private_data; 1569 1557 1570 - cam_err(cam, "Release, %d frames, %d singles, %d delivered\n", frames, 1558 + cam_dbg(cam, "Release, %d frames, %d singles, %d delivered\n", frames, 1571 1559 singles, delivered); 1572 1560 mutex_lock(&cam->s_mutex); 1573 1561 (cam->users)--; 1574 - if (filp == cam->owner) { 1575 - mcam_ctlr_stop_dma(cam); 1576 - cam->owner = NULL; 1577 - } 1578 1562 if (cam->users == 0) { 1563 + mcam_ctlr_stop_dma(cam); 1579 1564 mcam_cleanup_vb2(cam); 1580 1565 mcam_ctlr_power_down(cam); 1581 1566 if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read) ··· 1697 1688 if (irqs & (IRQ_EOF0 << frame)) { 1698 1689 mcam_frame_complete(cam, frame); 1699 1690 handled = 1; 1691 + if (cam->buffer_mode == B_DMA_sg) 1692 + break; 1700 1693 } 1701 1694 /* 1702 1695 * If a frame starts, note that we have DMA active. This
-1
drivers/media/video/marvell-ccic/mcam-core.h
··· 107 107 enum mcam_state state; 108 108 unsigned long flags; /* Buffer status, mainly (dev_lock) */ 109 109 int users; /* How many open FDs */ 110 - struct file *owner; /* Who has data access (v4l2) */ 111 110 112 111 /* 113 112 * Subsystem structures.
+9 -4
drivers/media/video/marvell-ccic/mmp-driver.c
··· 106 106 /* 107 107 * Power control. 108 108 */ 109 + static void mmpcam_power_up_ctlr(struct mmp_camera *cam) 110 + { 111 + iowrite32(0x3f, cam->power_regs + REG_CCIC_DCGCR); 112 + iowrite32(0x3805b, cam->power_regs + REG_CCIC_CRCR); 113 + mdelay(1); 114 + } 115 + 109 116 static void mmpcam_power_up(struct mcam_camera *mcam) 110 117 { 111 118 struct mmp_camera *cam = mcam_to_cam(mcam); ··· 120 113 /* 121 114 * Turn on power and clocks to the controller. 122 115 */ 123 - iowrite32(0x3f, cam->power_regs + REG_CCIC_DCGCR); 124 - iowrite32(0x3805b, cam->power_regs + REG_CCIC_CRCR); 125 - mdelay(1); 116 + mmpcam_power_up_ctlr(cam); 126 117 /* 127 118 * Provide power to the sensor. 128 119 */ ··· 340 335 * touch a register even if nothing was active before; trust 341 336 * me, it's better this way. 342 337 */ 343 - mmpcam_power_up(&cam->mcam); 338 + mmpcam_power_up_ctlr(cam); 344 339 return mccic_resume(&cam->mcam); 345 340 } 346 341
+1 -12
drivers/media/video/msp3400-driver.c
··· 881 881 .id_table = msp_id, 882 882 }; 883 883 884 - static __init int init_msp(void) 885 - { 886 - return i2c_add_driver(&msp_driver); 887 - } 888 - 889 - static __exit void exit_msp(void) 890 - { 891 - i2c_del_driver(&msp_driver); 892 - } 893 - 894 - module_init(init_msp); 895 - module_exit(exit_msp); 884 + module_i2c_driver(msp_driver); 896 885 897 886 /* 898 887 * Overrides for Emacs so that we follow Linus's tabbing style.
+1 -12
drivers/media/video/mt9m001.c
··· 730 730 .id_table = mt9m001_id, 731 731 }; 732 732 733 - static int __init mt9m001_mod_init(void) 734 - { 735 - return i2c_add_driver(&mt9m001_i2c_driver); 736 - } 737 - 738 - static void __exit mt9m001_mod_exit(void) 739 - { 740 - i2c_del_driver(&mt9m001_i2c_driver); 741 - } 742 - 743 - module_init(mt9m001_mod_init); 744 - module_exit(mt9m001_mod_exit); 733 + module_i2c_driver(mt9m001_i2c_driver); 745 734 746 735 MODULE_DESCRIPTION("Micron MT9M001 Camera driver"); 747 736 MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
+868
drivers/media/video/mt9m032.c
··· 1 + /* 2 + * Driver for MT9M032 CMOS Image Sensor from Micron 3 + * 4 + * Copyright (C) 2010-2011 Lund Engineering 5 + * Contact: Gil Lund <gwlund@lundeng.com> 6 + * Author: Martin Hostettler <martin@neutronstar.dyndns.org> 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * version 2 as published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, but 13 + * WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 + * 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., 51 Franklin St, Fifth Floor, Boston, MA 20 + * 02110-1301 USA 21 + */ 22 + 23 + #include <linux/delay.h> 24 + #include <linux/i2c.h> 25 + #include <linux/init.h> 26 + #include <linux/kernel.h> 27 + #include <linux/math64.h> 28 + #include <linux/module.h> 29 + #include <linux/mutex.h> 30 + #include <linux/slab.h> 31 + #include <linux/v4l2-mediabus.h> 32 + 33 + #include <media/media-entity.h> 34 + #include <media/mt9m032.h> 35 + #include <media/v4l2-ctrls.h> 36 + #include <media/v4l2-device.h> 37 + #include <media/v4l2-subdev.h> 38 + 39 + #include "aptina-pll.h" 40 + 41 + /* 42 + * width and height include active boundary and black parts 43 + * 44 + * column 0- 15 active boundary 45 + * column 16-1455 image 46 + * column 1456-1471 active boundary 47 + * column 1472-1599 black 48 + * 49 + * row 0- 51 black 50 + * row 53- 59 active boundary 51 + * row 60-1139 image 52 + * row 1140-1147 active boundary 53 + * row 1148-1151 black 54 + */ 55 + 56 + #define MT9M032_PIXEL_ARRAY_WIDTH 1600 57 + #define MT9M032_PIXEL_ARRAY_HEIGHT 1152 58 + 59 + #define MT9M032_CHIP_VERSION 0x00 60 + #define MT9M032_CHIP_VERSION_VALUE 0x1402 61 + #define MT9M032_ROW_START 0x01 62 + #define MT9M032_ROW_START_MIN 0 63 + #define MT9M032_ROW_START_MAX 1152 64 + #define MT9M032_ROW_START_DEF 60 65 + #define MT9M032_COLUMN_START 0x02 66 + #define MT9M032_COLUMN_START_MIN 0 67 + #define MT9M032_COLUMN_START_MAX 1600 68 + #define MT9M032_COLUMN_START_DEF 16 69 + #define MT9M032_ROW_SIZE 0x03 70 + #define MT9M032_ROW_SIZE_MIN 32 71 + #define MT9M032_ROW_SIZE_MAX 1152 72 + #define MT9M032_ROW_SIZE_DEF 1080 73 + #define MT9M032_COLUMN_SIZE 0x04 74 + #define MT9M032_COLUMN_SIZE_MIN 32 75 + #define MT9M032_COLUMN_SIZE_MAX 1600 76 + #define MT9M032_COLUMN_SIZE_DEF 1440 77 + #define MT9M032_HBLANK 0x05 78 + #define MT9M032_VBLANK 0x06 79 + #define MT9M032_VBLANK_MAX 0x7ff 80 + #define MT9M032_SHUTTER_WIDTH_HIGH 0x08 81 + #define MT9M032_SHUTTER_WIDTH_LOW 0x09 82 + #define MT9M032_SHUTTER_WIDTH_MIN 1 83 + #define MT9M032_SHUTTER_WIDTH_MAX 1048575 84 + #define MT9M032_SHUTTER_WIDTH_DEF 1943 85 + #define MT9M032_PIX_CLK_CTRL 0x0a 86 + #define MT9M032_PIX_CLK_CTRL_INV_PIXCLK 0x8000 87 + #define MT9M032_RESTART 0x0b 88 + #define MT9M032_RESET 0x0d 89 + #define MT9M032_PLL_CONFIG1 0x11 90 + #define MT9M032_PLL_CONFIG1_OUTDIV_MASK 0x3f 91 + #define MT9M032_PLL_CONFIG1_MUL_SHIFT 8 92 + #define MT9M032_READ_MODE1 0x1e 93 + #define MT9M032_READ_MODE2 0x20 94 + #define MT9M032_READ_MODE2_VFLIP_SHIFT 15 95 + #define MT9M032_READ_MODE2_HFLIP_SHIFT 14 96 + #define MT9M032_READ_MODE2_ROW_BLC 0x40 97 + #define MT9M032_GAIN_GREEN1 0x2b 98 + #define MT9M032_GAIN_BLUE 0x2c 99 + #define MT9M032_GAIN_RED 0x2d 100 + #define MT9M032_GAIN_GREEN2 0x2e 101 + 102 + /* write only */ 103 + #define MT9M032_GAIN_ALL 0x35 104 + #define MT9M032_GAIN_DIGITAL_MASK 0x7f 105 + #define MT9M032_GAIN_DIGITAL_SHIFT 8 106 + #define MT9M032_GAIN_AMUL_SHIFT 6 107 + #define MT9M032_GAIN_ANALOG_MASK 0x3f 108 + #define MT9M032_FORMATTER1 0x9e 109 + #define MT9M032_FORMATTER2 0x9f 110 + #define MT9M032_FORMATTER2_DOUT_EN 0x1000 111 + #define MT9M032_FORMATTER2_PIXCLK_EN 0x2000 112 + 113 + /* 114 + * The available MT9M032 datasheet is missing documentation for register 0x10 115 + * MT9P031 seems to be close enough, so use constants from that datasheet for 116 + * now. 117 + * But keep the name MT9P031 to remind us, that this isn't really confirmed 118 + * for this sensor. 119 + */ 120 + #define MT9P031_PLL_CONTROL 0x10 121 + #define MT9P031_PLL_CONTROL_PWROFF 0x0050 122 + #define MT9P031_PLL_CONTROL_PWRON 0x0051 123 + #define MT9P031_PLL_CONTROL_USEPLL 0x0052 124 + #define MT9P031_PLL_CONFIG2 0x11 125 + #define MT9P031_PLL_CONFIG2_P1_DIV_MASK 0x1f 126 + 127 + struct mt9m032 { 128 + struct v4l2_subdev subdev; 129 + struct media_pad pad; 130 + struct mt9m032_platform_data *pdata; 131 + 132 + unsigned int pix_clock; 133 + 134 + struct v4l2_ctrl_handler ctrls; 135 + struct { 136 + struct v4l2_ctrl *hflip; 137 + struct v4l2_ctrl *vflip; 138 + }; 139 + 140 + struct mutex lock; /* Protects streaming, format, interval and crop */ 141 + 142 + bool streaming; 143 + 144 + struct v4l2_mbus_framefmt format; 145 + struct v4l2_rect crop; 146 + struct v4l2_fract frame_interval; 147 + }; 148 + 149 + #define to_mt9m032(sd) container_of(sd, struct mt9m032, subdev) 150 + #define to_dev(sensor) \ 151 + (&((struct i2c_client *)v4l2_get_subdevdata(&(sensor)->subdev))->dev) 152 + 153 + static int mt9m032_read(struct i2c_client *client, u8 reg) 154 + { 155 + return i2c_smbus_read_word_swapped(client, reg); 156 + } 157 + 158 + static int mt9m032_write(struct i2c_client *client, u8 reg, const u16 data) 159 + { 160 + return i2c_smbus_write_word_swapped(client, reg, data); 161 + } 162 + 163 + static u32 mt9m032_row_time(struct mt9m032 *sensor, unsigned int width) 164 + { 165 + unsigned int effective_width; 166 + u32 ns; 167 + 168 + effective_width = width + 716; /* empirical value */ 169 + ns = div_u64(1000000000ULL * effective_width, sensor->pix_clock); 170 + dev_dbg(to_dev(sensor), "MT9M032 line time: %u ns\n", ns); 171 + return ns; 172 + } 173 + 174 + static int mt9m032_update_timing(struct mt9m032 *sensor, 175 + struct v4l2_fract *interval) 176 + { 177 + struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); 178 + struct v4l2_rect *crop = &sensor->crop; 179 + unsigned int min_vblank; 180 + unsigned int vblank; 181 + u32 row_time; 182 + 183 + if (!interval) 184 + interval = &sensor->frame_interval; 185 + 186 + row_time = mt9m032_row_time(sensor, crop->width); 187 + 188 + vblank = div_u64(1000000000ULL * interval->numerator, 189 + (u64)row_time * interval->denominator) 190 + - crop->height; 191 + 192 + if (vblank > MT9M032_VBLANK_MAX) { 193 + /* hardware limits to 11 bit values */ 194 + interval->denominator = 1000; 195 + interval->numerator = 196 + div_u64((crop->height + MT9M032_VBLANK_MAX) * 197 + (u64)row_time * interval->denominator, 198 + 1000000000ULL); 199 + vblank = div_u64(1000000000ULL * interval->numerator, 200 + (u64)row_time * interval->denominator) 201 + - crop->height; 202 + } 203 + /* enforce minimal 1.6ms blanking time. */ 204 + min_vblank = 1600000 / row_time; 205 + vblank = clamp_t(unsigned int, vblank, min_vblank, MT9M032_VBLANK_MAX); 206 + 207 + return mt9m032_write(client, MT9M032_VBLANK, vblank); 208 + } 209 + 210 + static int mt9m032_update_geom_timing(struct mt9m032 *sensor) 211 + { 212 + struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); 213 + int ret; 214 + 215 + ret = mt9m032_write(client, MT9M032_COLUMN_SIZE, 216 + sensor->crop.width - 1); 217 + if (!ret) 218 + ret = mt9m032_write(client, MT9M032_ROW_SIZE, 219 + sensor->crop.height - 1); 220 + if (!ret) 221 + ret = mt9m032_write(client, MT9M032_COLUMN_START, 222 + sensor->crop.left); 223 + if (!ret) 224 + ret = mt9m032_write(client, MT9M032_ROW_START, 225 + sensor->crop.top); 226 + if (!ret) 227 + ret = mt9m032_update_timing(sensor, NULL); 228 + return ret; 229 + } 230 + 231 + static int update_formatter2(struct mt9m032 *sensor, bool streaming) 232 + { 233 + struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); 234 + u16 reg_val = MT9M032_FORMATTER2_DOUT_EN 235 + | 0x0070; /* parts reserved! */ 236 + /* possibly for changing to 14-bit mode */ 237 + 238 + if (streaming) 239 + reg_val |= MT9M032_FORMATTER2_PIXCLK_EN; /* pixclock enable */ 240 + 241 + return mt9m032_write(client, MT9M032_FORMATTER2, reg_val); 242 + } 243 + 244 + static int mt9m032_setup_pll(struct mt9m032 *sensor) 245 + { 246 + static const struct aptina_pll_limits limits = { 247 + .ext_clock_min = 8000000, 248 + .ext_clock_max = 16500000, 249 + .int_clock_min = 2000000, 250 + .int_clock_max = 24000000, 251 + .out_clock_min = 322000000, 252 + .out_clock_max = 693000000, 253 + .pix_clock_max = 99000000, 254 + .n_min = 1, 255 + .n_max = 64, 256 + .m_min = 16, 257 + .m_max = 255, 258 + .p1_min = 1, 259 + .p1_max = 128, 260 + }; 261 + 262 + struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); 263 + struct mt9m032_platform_data *pdata = sensor->pdata; 264 + struct aptina_pll pll; 265 + int ret; 266 + 267 + pll.ext_clock = pdata->ext_clock; 268 + pll.pix_clock = pdata->pix_clock; 269 + 270 + ret = aptina_pll_calculate(&client->dev, &limits, &pll); 271 + if (ret < 0) 272 + return ret; 273 + 274 + sensor->pix_clock = pdata->pix_clock; 275 + 276 + ret = mt9m032_write(client, MT9M032_PLL_CONFIG1, 277 + (pll.m << MT9M032_PLL_CONFIG1_MUL_SHIFT) 278 + | (pll.p1 - 1)); 279 + if (!ret) 280 + ret = mt9m032_write(client, MT9P031_PLL_CONFIG2, pll.n - 1); 281 + if (!ret) 282 + ret = mt9m032_write(client, MT9P031_PLL_CONTROL, 283 + MT9P031_PLL_CONTROL_PWRON | 284 + MT9P031_PLL_CONTROL_USEPLL); 285 + if (!ret) /* more reserved, Continuous, Master Mode */ 286 + ret = mt9m032_write(client, MT9M032_READ_MODE1, 0x8006); 287 + if (!ret) /* Set 14-bit mode, select 7 divider */ 288 + ret = mt9m032_write(client, MT9M032_FORMATTER1, 0x111e); 289 + 290 + return ret; 291 + } 292 + 293 + /* ----------------------------------------------------------------------------- 294 + * Subdev pad operations 295 + */ 296 + 297 + static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev, 298 + struct v4l2_subdev_fh *fh, 299 + struct v4l2_subdev_mbus_code_enum *code) 300 + { 301 + if (code->index != 0) 302 + return -EINVAL; 303 + 304 + code->code = V4L2_MBUS_FMT_Y8_1X8; 305 + return 0; 306 + } 307 + 308 + static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev, 309 + struct v4l2_subdev_fh *fh, 310 + struct v4l2_subdev_frame_size_enum *fse) 311 + { 312 + if (fse->index != 0 || fse->code != V4L2_MBUS_FMT_Y8_1X8) 313 + return -EINVAL; 314 + 315 + fse->min_width = MT9M032_COLUMN_SIZE_DEF; 316 + fse->max_width = MT9M032_COLUMN_SIZE_DEF; 317 + fse->min_height = MT9M032_ROW_SIZE_DEF; 318 + fse->max_height = MT9M032_ROW_SIZE_DEF; 319 + 320 + return 0; 321 + } 322 + 323 + /** 324 + * __mt9m032_get_pad_crop() - get crop rect 325 + * @sensor: pointer to the sensor struct 326 + * @fh: file handle for getting the try crop rect from 327 + * @which: select try or active crop rect 328 + * 329 + * Returns a pointer the current active or fh relative try crop rect 330 + */ 331 + static struct v4l2_rect * 332 + __mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh, 333 + enum v4l2_subdev_format_whence which) 334 + { 335 + switch (which) { 336 + case V4L2_SUBDEV_FORMAT_TRY: 337 + return v4l2_subdev_get_try_crop(fh, 0); 338 + case V4L2_SUBDEV_FORMAT_ACTIVE: 339 + return &sensor->crop; 340 + default: 341 + return NULL; 342 + } 343 + } 344 + 345 + /** 346 + * __mt9m032_get_pad_format() - get format 347 + * @sensor: pointer to the sensor struct 348 + * @fh: file handle for getting the try format from 349 + * @which: select try or active format 350 + * 351 + * Returns a pointer the current active or fh relative try format 352 + */ 353 + static struct v4l2_mbus_framefmt * 354 + __mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh, 355 + enum v4l2_subdev_format_whence which) 356 + { 357 + switch (which) { 358 + case V4L2_SUBDEV_FORMAT_TRY: 359 + return v4l2_subdev_get_try_format(fh, 0); 360 + case V4L2_SUBDEV_FORMAT_ACTIVE: 361 + return &sensor->format; 362 + default: 363 + return NULL; 364 + } 365 + } 366 + 367 + static int mt9m032_get_pad_format(struct v4l2_subdev *subdev, 368 + struct v4l2_subdev_fh *fh, 369 + struct v4l2_subdev_format *fmt) 370 + { 371 + struct mt9m032 *sensor = to_mt9m032(subdev); 372 + 373 + mutex_lock(&sensor->lock); 374 + fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); 375 + mutex_unlock(&sensor->lock); 376 + 377 + return 0; 378 + } 379 + 380 + static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, 381 + struct v4l2_subdev_fh *fh, 382 + struct v4l2_subdev_format *fmt) 383 + { 384 + struct mt9m032 *sensor = to_mt9m032(subdev); 385 + int ret; 386 + 387 + mutex_lock(&sensor->lock); 388 + 389 + if (sensor->streaming && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 390 + ret = -EBUSY; 391 + goto done; 392 + } 393 + 394 + /* Scaling is not supported, the format is thus fixed. */ 395 + ret = mt9m032_get_pad_format(subdev, fh, fmt); 396 + 397 + done: 398 + mutex_lock(&sensor->lock); 399 + return ret; 400 + } 401 + 402 + static int mt9m032_get_pad_crop(struct v4l2_subdev *subdev, 403 + struct v4l2_subdev_fh *fh, 404 + struct v4l2_subdev_crop *crop) 405 + { 406 + struct mt9m032 *sensor = to_mt9m032(subdev); 407 + 408 + mutex_lock(&sensor->lock); 409 + crop->rect = *__mt9m032_get_pad_crop(sensor, fh, crop->which); 410 + mutex_unlock(&sensor->lock); 411 + 412 + return 0; 413 + } 414 + 415 + static int mt9m032_set_pad_crop(struct v4l2_subdev *subdev, 416 + struct v4l2_subdev_fh *fh, 417 + struct v4l2_subdev_crop *crop) 418 + { 419 + struct mt9m032 *sensor = to_mt9m032(subdev); 420 + struct v4l2_mbus_framefmt *format; 421 + struct v4l2_rect *__crop; 422 + struct v4l2_rect rect; 423 + int ret = 0; 424 + 425 + mutex_lock(&sensor->lock); 426 + 427 + if (sensor->streaming && crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 428 + ret = -EBUSY; 429 + goto done; 430 + } 431 + 432 + /* Clamp the crop rectangle boundaries and align them to a multiple of 2 433 + * pixels to ensure a GRBG Bayer pattern. 434 + */ 435 + rect.left = clamp(ALIGN(crop->rect.left, 2), MT9M032_COLUMN_START_MIN, 436 + MT9M032_COLUMN_START_MAX); 437 + rect.top = clamp(ALIGN(crop->rect.top, 2), MT9M032_ROW_START_MIN, 438 + MT9M032_ROW_START_MAX); 439 + rect.width = clamp(ALIGN(crop->rect.width, 2), MT9M032_COLUMN_SIZE_MIN, 440 + MT9M032_COLUMN_SIZE_MAX); 441 + rect.height = clamp(ALIGN(crop->rect.height, 2), MT9M032_ROW_SIZE_MIN, 442 + MT9M032_ROW_SIZE_MAX); 443 + 444 + rect.width = min(rect.width, MT9M032_PIXEL_ARRAY_WIDTH - rect.left); 445 + rect.height = min(rect.height, MT9M032_PIXEL_ARRAY_HEIGHT - rect.top); 446 + 447 + __crop = __mt9m032_get_pad_crop(sensor, fh, crop->which); 448 + 449 + if (rect.width != __crop->width || rect.height != __crop->height) { 450 + /* Reset the output image size if the crop rectangle size has 451 + * been modified. 452 + */ 453 + format = __mt9m032_get_pad_format(sensor, fh, crop->which); 454 + format->width = rect.width; 455 + format->height = rect.height; 456 + } 457 + 458 + *__crop = rect; 459 + crop->rect = rect; 460 + 461 + if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) 462 + ret = mt9m032_update_geom_timing(sensor); 463 + 464 + done: 465 + mutex_unlock(&sensor->lock); 466 + return ret; 467 + } 468 + 469 + static int mt9m032_get_frame_interval(struct v4l2_subdev *subdev, 470 + struct v4l2_subdev_frame_interval *fi) 471 + { 472 + struct mt9m032 *sensor = to_mt9m032(subdev); 473 + 474 + mutex_lock(&sensor->lock); 475 + memset(fi, 0, sizeof(*fi)); 476 + fi->interval = sensor->frame_interval; 477 + mutex_unlock(&sensor->lock); 478 + 479 + return 0; 480 + } 481 + 482 + static int mt9m032_set_frame_interval(struct v4l2_subdev *subdev, 483 + struct v4l2_subdev_frame_interval *fi) 484 + { 485 + struct mt9m032 *sensor = to_mt9m032(subdev); 486 + int ret; 487 + 488 + mutex_lock(&sensor->lock); 489 + 490 + if (sensor->streaming) { 491 + ret = -EBUSY; 492 + goto done; 493 + } 494 + 495 + /* Avoid divisions by 0. */ 496 + if (fi->interval.denominator == 0) 497 + fi->interval.denominator = 1; 498 + 499 + ret = mt9m032_update_timing(sensor, &fi->interval); 500 + if (!ret) 501 + sensor->frame_interval = fi->interval; 502 + 503 + done: 504 + mutex_unlock(&sensor->lock); 505 + return ret; 506 + } 507 + 508 + static int mt9m032_s_stream(struct v4l2_subdev *subdev, int streaming) 509 + { 510 + struct mt9m032 *sensor = to_mt9m032(subdev); 511 + int ret; 512 + 513 + mutex_lock(&sensor->lock); 514 + ret = update_formatter2(sensor, streaming); 515 + if (!ret) 516 + sensor->streaming = streaming; 517 + mutex_unlock(&sensor->lock); 518 + 519 + return ret; 520 + } 521 + 522 + /* ----------------------------------------------------------------------------- 523 + * V4L2 subdev core operations 524 + */ 525 + 526 + #ifdef CONFIG_VIDEO_ADV_DEBUG 527 + static int mt9m032_g_register(struct v4l2_subdev *sd, 528 + struct v4l2_dbg_register *reg) 529 + { 530 + struct mt9m032 *sensor = to_mt9m032(sd); 531 + struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); 532 + int val; 533 + 534 + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 535 + return -EINVAL; 536 + if (reg->match.addr != client->addr) 537 + return -ENODEV; 538 + 539 + val = mt9m032_read(client, reg->reg); 540 + if (val < 0) 541 + return -EIO; 542 + 543 + reg->size = 2; 544 + reg->val = val; 545 + 546 + return 0; 547 + } 548 + 549 + static int mt9m032_s_register(struct v4l2_subdev *sd, 550 + struct v4l2_dbg_register *reg) 551 + { 552 + struct mt9m032 *sensor = to_mt9m032(sd); 553 + struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); 554 + 555 + if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 556 + return -EINVAL; 557 + 558 + if (reg->match.addr != client->addr) 559 + return -ENODEV; 560 + 561 + return mt9m032_write(client, reg->reg, reg->val); 562 + } 563 + #endif 564 + 565 + /* ----------------------------------------------------------------------------- 566 + * V4L2 subdev control operations 567 + */ 568 + 569 + static int update_read_mode2(struct mt9m032 *sensor, bool vflip, bool hflip) 570 + { 571 + struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); 572 + int reg_val = (vflip << MT9M032_READ_MODE2_VFLIP_SHIFT) 573 + | (hflip << MT9M032_READ_MODE2_HFLIP_SHIFT) 574 + | MT9M032_READ_MODE2_ROW_BLC 575 + | 0x0007; 576 + 577 + return mt9m032_write(client, MT9M032_READ_MODE2, reg_val); 578 + } 579 + 580 + static int mt9m032_set_gain(struct mt9m032 *sensor, s32 val) 581 + { 582 + struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); 583 + int digital_gain_val; /* in 1/8th (0..127) */ 584 + int analog_mul; /* 0 or 1 */ 585 + int analog_gain_val; /* in 1/16th. (0..63) */ 586 + u16 reg_val; 587 + 588 + digital_gain_val = 51; /* from setup example */ 589 + 590 + if (val < 63) { 591 + analog_mul = 0; 592 + analog_gain_val = val; 593 + } else { 594 + analog_mul = 1; 595 + analog_gain_val = val / 2; 596 + } 597 + 598 + /* a_gain = (1 + analog_mul) + (analog_gain_val + 1) / 16 */ 599 + /* overall_gain = a_gain * (1 + digital_gain_val / 8) */ 600 + 601 + reg_val = ((digital_gain_val & MT9M032_GAIN_DIGITAL_MASK) 602 + << MT9M032_GAIN_DIGITAL_SHIFT) 603 + | ((analog_mul & 1) << MT9M032_GAIN_AMUL_SHIFT) 604 + | (analog_gain_val & MT9M032_GAIN_ANALOG_MASK); 605 + 606 + return mt9m032_write(client, MT9M032_GAIN_ALL, reg_val); 607 + } 608 + 609 + static int mt9m032_try_ctrl(struct v4l2_ctrl *ctrl) 610 + { 611 + if (ctrl->id == V4L2_CID_GAIN && ctrl->val >= 63) { 612 + /* round because of multiplier used for values >= 63 */ 613 + ctrl->val &= ~1; 614 + } 615 + 616 + return 0; 617 + } 618 + 619 + static int mt9m032_set_ctrl(struct v4l2_ctrl *ctrl) 620 + { 621 + struct mt9m032 *sensor = 622 + container_of(ctrl->handler, struct mt9m032, ctrls); 623 + struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); 624 + int ret; 625 + 626 + switch (ctrl->id) { 627 + case V4L2_CID_GAIN: 628 + return mt9m032_set_gain(sensor, ctrl->val); 629 + 630 + case V4L2_CID_HFLIP: 631 + /* case V4L2_CID_VFLIP: -- In the same cluster */ 632 + return update_read_mode2(sensor, sensor->vflip->val, 633 + sensor->hflip->val); 634 + 635 + case V4L2_CID_EXPOSURE: 636 + ret = mt9m032_write(client, MT9M032_SHUTTER_WIDTH_HIGH, 637 + (ctrl->val >> 16) & 0xffff); 638 + if (ret < 0) 639 + return ret; 640 + 641 + return mt9m032_write(client, MT9M032_SHUTTER_WIDTH_LOW, 642 + ctrl->val & 0xffff); 643 + } 644 + 645 + return 0; 646 + } 647 + 648 + static struct v4l2_ctrl_ops mt9m032_ctrl_ops = { 649 + .s_ctrl = mt9m032_set_ctrl, 650 + .try_ctrl = mt9m032_try_ctrl, 651 + }; 652 + 653 + /* -------------------------------------------------------------------------- */ 654 + 655 + static const struct v4l2_subdev_core_ops mt9m032_core_ops = { 656 + #ifdef CONFIG_VIDEO_ADV_DEBUG 657 + .g_register = mt9m032_g_register, 658 + .s_register = mt9m032_s_register, 659 + #endif 660 + }; 661 + 662 + static const struct v4l2_subdev_video_ops mt9m032_video_ops = { 663 + .s_stream = mt9m032_s_stream, 664 + .g_frame_interval = mt9m032_get_frame_interval, 665 + .s_frame_interval = mt9m032_set_frame_interval, 666 + }; 667 + 668 + static const struct v4l2_subdev_pad_ops mt9m032_pad_ops = { 669 + .enum_mbus_code = mt9m032_enum_mbus_code, 670 + .enum_frame_size = mt9m032_enum_frame_size, 671 + .get_fmt = mt9m032_get_pad_format, 672 + .set_fmt = mt9m032_set_pad_format, 673 + .set_crop = mt9m032_set_pad_crop, 674 + .get_crop = mt9m032_get_pad_crop, 675 + }; 676 + 677 + static const struct v4l2_subdev_ops mt9m032_ops = { 678 + .core = &mt9m032_core_ops, 679 + .video = &mt9m032_video_ops, 680 + .pad = &mt9m032_pad_ops, 681 + }; 682 + 683 + /* ----------------------------------------------------------------------------- 684 + * Driver initialization and probing 685 + */ 686 + 687 + static int mt9m032_probe(struct i2c_client *client, 688 + const struct i2c_device_id *devid) 689 + { 690 + struct i2c_adapter *adapter = client->adapter; 691 + struct mt9m032 *sensor; 692 + int chip_version; 693 + int ret; 694 + 695 + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { 696 + dev_warn(&client->dev, 697 + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); 698 + return -EIO; 699 + } 700 + 701 + if (!client->dev.platform_data) 702 + return -ENODEV; 703 + 704 + sensor = kzalloc(sizeof(*sensor), GFP_KERNEL); 705 + if (sensor == NULL) 706 + return -ENOMEM; 707 + 708 + mutex_init(&sensor->lock); 709 + 710 + sensor->pdata = client->dev.platform_data; 711 + 712 + v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops); 713 + sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 714 + 715 + chip_version = mt9m032_read(client, MT9M032_CHIP_VERSION); 716 + if (chip_version != MT9M032_CHIP_VERSION_VALUE) { 717 + dev_err(&client->dev, "MT9M032 not detected, wrong version " 718 + "0x%04x\n", chip_version); 719 + ret = -ENODEV; 720 + goto error_sensor; 721 + } 722 + 723 + dev_info(&client->dev, "MT9M032 detected at address 0x%02x\n", 724 + client->addr); 725 + 726 + sensor->frame_interval.numerator = 1; 727 + sensor->frame_interval.denominator = 30; 728 + 729 + sensor->crop.left = MT9M032_COLUMN_START_DEF; 730 + sensor->crop.top = MT9M032_ROW_START_DEF; 731 + sensor->crop.width = MT9M032_COLUMN_SIZE_DEF; 732 + sensor->crop.height = MT9M032_ROW_SIZE_DEF; 733 + 734 + sensor->format.width = sensor->crop.width; 735 + sensor->format.height = sensor->crop.height; 736 + sensor->format.code = V4L2_MBUS_FMT_Y8_1X8; 737 + sensor->format.field = V4L2_FIELD_NONE; 738 + sensor->format.colorspace = V4L2_COLORSPACE_SRGB; 739 + 740 + v4l2_ctrl_handler_init(&sensor->ctrls, 4); 741 + 742 + v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops, 743 + V4L2_CID_GAIN, 0, 127, 1, 64); 744 + 745 + sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls, 746 + &mt9m032_ctrl_ops, 747 + V4L2_CID_HFLIP, 0, 1, 1, 0); 748 + sensor->vflip = v4l2_ctrl_new_std(&sensor->ctrls, 749 + &mt9m032_ctrl_ops, 750 + V4L2_CID_VFLIP, 0, 1, 1, 0); 751 + 752 + v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops, 753 + V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN, 754 + MT9M032_SHUTTER_WIDTH_MAX, 1, 755 + MT9M032_SHUTTER_WIDTH_DEF); 756 + 757 + if (sensor->ctrls.error) { 758 + ret = sensor->ctrls.error; 759 + dev_err(&client->dev, "control initialization error %d\n", ret); 760 + goto error_ctrl; 761 + } 762 + 763 + v4l2_ctrl_cluster(2, &sensor->hflip); 764 + 765 + sensor->subdev.ctrl_handler = &sensor->ctrls; 766 + sensor->pad.flags = MEDIA_PAD_FL_SOURCE; 767 + ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0); 768 + if (ret < 0) 769 + goto error_ctrl; 770 + 771 + ret = mt9m032_write(client, MT9M032_RESET, 1); /* reset on */ 772 + if (ret < 0) 773 + goto error_entity; 774 + mt9m032_write(client, MT9M032_RESET, 0); /* reset off */ 775 + if (ret < 0) 776 + goto error_entity; 777 + 778 + ret = mt9m032_setup_pll(sensor); 779 + if (ret < 0) 780 + goto error_entity; 781 + usleep_range(10000, 11000); 782 + 783 + ret = v4l2_ctrl_handler_setup(&sensor->ctrls); 784 + if (ret < 0) 785 + goto error_entity; 786 + 787 + /* SIZE */ 788 + ret = mt9m032_update_geom_timing(sensor); 789 + if (ret < 0) 790 + goto error_entity; 791 + 792 + ret = mt9m032_write(client, 0x41, 0x0000); /* reserved !!! */ 793 + if (ret < 0) 794 + goto error_entity; 795 + ret = mt9m032_write(client, 0x42, 0x0003); /* reserved !!! */ 796 + if (ret < 0) 797 + goto error_entity; 798 + ret = mt9m032_write(client, 0x43, 0x0003); /* reserved !!! */ 799 + if (ret < 0) 800 + goto error_entity; 801 + ret = mt9m032_write(client, 0x7f, 0x0000); /* reserved !!! */ 802 + if (ret < 0) 803 + goto error_entity; 804 + if (sensor->pdata->invert_pixclock) { 805 + ret = mt9m032_write(client, MT9M032_PIX_CLK_CTRL, 806 + MT9M032_PIX_CLK_CTRL_INV_PIXCLK); 807 + if (ret < 0) 808 + goto error_entity; 809 + } 810 + 811 + ret = mt9m032_write(client, MT9M032_RESTART, 1); /* Restart on */ 812 + if (ret < 0) 813 + goto error_entity; 814 + msleep(100); 815 + ret = mt9m032_write(client, MT9M032_RESTART, 0); /* Restart off */ 816 + if (ret < 0) 817 + goto error_entity; 818 + msleep(100); 819 + ret = update_formatter2(sensor, false); 820 + if (ret < 0) 821 + goto error_entity; 822 + 823 + return ret; 824 + 825 + error_entity: 826 + media_entity_cleanup(&sensor->subdev.entity); 827 + error_ctrl: 828 + v4l2_ctrl_handler_free(&sensor->ctrls); 829 + error_sensor: 830 + mutex_destroy(&sensor->lock); 831 + kfree(sensor); 832 + return ret; 833 + } 834 + 835 + static int mt9m032_remove(struct i2c_client *client) 836 + { 837 + struct v4l2_subdev *subdev = i2c_get_clientdata(client); 838 + struct mt9m032 *sensor = to_mt9m032(subdev); 839 + 840 + v4l2_device_unregister_subdev(&sensor->subdev); 841 + v4l2_ctrl_handler_free(&sensor->ctrls); 842 + media_entity_cleanup(&sensor->subdev.entity); 843 + mutex_destroy(&sensor->lock); 844 + kfree(sensor); 845 + return 0; 846 + } 847 + 848 + static const struct i2c_device_id mt9m032_id_table[] = { 849 + { MT9M032_NAME, 0 }, 850 + { } 851 + }; 852 + 853 + MODULE_DEVICE_TABLE(i2c, mt9m032_id_table); 854 + 855 + static struct i2c_driver mt9m032_i2c_driver = { 856 + .driver = { 857 + .name = MT9M032_NAME, 858 + }, 859 + .probe = mt9m032_probe, 860 + .remove = mt9m032_remove, 861 + .id_table = mt9m032_id_table, 862 + }; 863 + 864 + module_i2c_driver(mt9m032_i2c_driver); 865 + 866 + MODULE_AUTHOR("Martin Hostettler <martin@neutronstar.dyndns.org>"); 867 + MODULE_DESCRIPTION("MT9M032 camera sensor driver"); 868 + MODULE_LICENSE("GPL v2");
+1 -12
drivers/media/video/mt9m111.c
··· 1008 1008 .id_table = mt9m111_id, 1009 1009 }; 1010 1010 1011 - static int __init mt9m111_mod_init(void) 1012 - { 1013 - return i2c_add_driver(&mt9m111_i2c_driver); 1014 - } 1015 - 1016 - static void __exit mt9m111_mod_exit(void) 1017 - { 1018 - i2c_del_driver(&mt9m111_i2c_driver); 1019 - } 1020 - 1021 - module_init(mt9m111_mod_init); 1022 - module_exit(mt9m111_mod_exit); 1011 + module_i2c_driver(mt9m111_i2c_driver); 1023 1012 1024 1013 MODULE_DESCRIPTION("Micron/Aptina MT9M111/MT9M112/MT9M131 Camera driver"); 1025 1014 MODULE_AUTHOR("Robert Jarzmik");
+28 -52
drivers/media/video/mt9p031.c
··· 19 19 #include <linux/log2.h> 20 20 #include <linux/pm.h> 21 21 #include <linux/slab.h> 22 - #include <media/v4l2-subdev.h> 23 22 #include <linux/videodev2.h> 24 23 25 24 #include <media/mt9p031.h> ··· 26 27 #include <media/v4l2-ctrls.h> 27 28 #include <media/v4l2-device.h> 28 29 #include <media/v4l2-subdev.h> 30 + 31 + #include "aptina-pll.h" 29 32 30 33 #define MT9P031_PIXEL_ARRAY_WIDTH 2752 31 34 #define MT9P031_PIXEL_ARRAY_HEIGHT 2004 ··· 99 98 #define MT9P031_TEST_PATTERN_RED 0xa2 100 99 #define MT9P031_TEST_PATTERN_BLUE 0xa3 101 100 102 - struct mt9p031_pll_divs { 103 - u32 ext_freq; 104 - u32 target_freq; 105 - u8 m; 106 - u8 n; 107 - u8 p1; 108 - }; 109 - 110 101 struct mt9p031 { 111 102 struct v4l2_subdev subdev; 112 103 struct media_pad pad; ··· 108 115 struct mt9p031_platform_data *pdata; 109 116 struct mutex power_lock; /* lock to protect power_count */ 110 117 int power_count; 111 - u16 xskip; 112 - u16 yskip; 113 118 114 - const struct mt9p031_pll_divs *pll; 119 + struct aptina_pll pll; 115 120 116 121 /* Registers cache */ 117 122 u16 output_control; ··· 177 186 0); 178 187 } 179 188 180 - /* 181 - * This static table uses ext_freq and vdd_io values to select suitable 182 - * PLL dividers m, n and p1 which have been calculated as specifiec in p36 183 - * of Aptina's mt9p031 datasheet. New values should be added here. 184 - */ 185 - static const struct mt9p031_pll_divs mt9p031_divs[] = { 186 - /* ext_freq target_freq m n p1 */ 187 - {21000000, 48000000, 26, 2, 6} 188 - }; 189 - 190 - static int mt9p031_pll_get_divs(struct mt9p031 *mt9p031) 189 + static int mt9p031_pll_setup(struct mt9p031 *mt9p031) 191 190 { 191 + static const struct aptina_pll_limits limits = { 192 + .ext_clock_min = 6000000, 193 + .ext_clock_max = 27000000, 194 + .int_clock_min = 2000000, 195 + .int_clock_max = 13500000, 196 + .out_clock_min = 180000000, 197 + .out_clock_max = 360000000, 198 + .pix_clock_max = 96000000, 199 + .n_min = 1, 200 + .n_max = 64, 201 + .m_min = 16, 202 + .m_max = 255, 203 + .p1_min = 1, 204 + .p1_max = 128, 205 + }; 206 + 192 207 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); 193 - int i; 208 + struct mt9p031_platform_data *pdata = mt9p031->pdata; 194 209 195 - for (i = 0; i < ARRAY_SIZE(mt9p031_divs); i++) { 196 - if (mt9p031_divs[i].ext_freq == mt9p031->pdata->ext_freq && 197 - mt9p031_divs[i].target_freq == mt9p031->pdata->target_freq) { 198 - mt9p031->pll = &mt9p031_divs[i]; 199 - return 0; 200 - } 201 - } 210 + mt9p031->pll.ext_clock = pdata->ext_freq; 211 + mt9p031->pll.pix_clock = pdata->target_freq; 202 212 203 - dev_err(&client->dev, "Couldn't find PLL dividers for ext_freq = %d, " 204 - "target_freq = %d\n", mt9p031->pdata->ext_freq, 205 - mt9p031->pdata->target_freq); 206 - return -EINVAL; 213 + return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll); 207 214 } 208 215 209 216 static int mt9p031_pll_enable(struct mt9p031 *mt9p031) ··· 215 226 return ret; 216 227 217 228 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_1, 218 - (mt9p031->pll->m << 8) | (mt9p031->pll->n - 1)); 229 + (mt9p031->pll.m << 8) | (mt9p031->pll.n - 1)); 219 230 if (ret < 0) 220 231 return ret; 221 232 222 - ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll->p1 - 1); 233 + ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll.p1 - 1); 223 234 if (ret < 0) 224 235 return ret; 225 236 ··· 774 785 format->field = V4L2_FIELD_NONE; 775 786 format->colorspace = V4L2_COLORSPACE_SRGB; 776 787 777 - mt9p031->xskip = 1; 778 - mt9p031->yskip = 1; 779 788 return mt9p031_set_power(subdev, 1); 780 789 } 781 790 ··· 892 905 mt9p031->format.field = V4L2_FIELD_NONE; 893 906 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB; 894 907 895 - ret = mt9p031_pll_get_divs(mt9p031); 908 + ret = mt9p031_pll_setup(mt9p031); 896 909 897 910 done: 898 911 if (ret < 0) { ··· 932 945 .id_table = mt9p031_id, 933 946 }; 934 947 935 - static int __init mt9p031_mod_init(void) 936 - { 937 - return i2c_add_driver(&mt9p031_i2c_driver); 938 - } 939 - 940 - static void __exit mt9p031_mod_exit(void) 941 - { 942 - i2c_del_driver(&mt9p031_i2c_driver); 943 - } 944 - 945 - module_init(mt9p031_mod_init); 946 - module_exit(mt9p031_mod_exit); 948 + module_i2c_driver(mt9p031_i2c_driver); 947 949 948 950 MODULE_DESCRIPTION("Aptina MT9P031 Camera driver"); 949 951 MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
+1 -12
drivers/media/video/mt9t001.c
··· 817 817 .id_table = mt9t001_id, 818 818 }; 819 819 820 - static int __init mt9t001_init(void) 821 - { 822 - return i2c_add_driver(&mt9t001_driver); 823 - } 824 - 825 - static void __exit mt9t001_exit(void) 826 - { 827 - i2c_del_driver(&mt9t001_driver); 828 - } 829 - 830 - module_init(mt9t001_init); 831 - module_exit(mt9t001_exit); 820 + module_i2c_driver(mt9t001_driver); 832 821 833 822 MODULE_DESCRIPTION("Aptina (Micron) MT9T001 Camera driver"); 834 823 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+1 -12
drivers/media/video/mt9t031.c
··· 850 850 .id_table = mt9t031_id, 851 851 }; 852 852 853 - static int __init mt9t031_mod_init(void) 854 - { 855 - return i2c_add_driver(&mt9t031_i2c_driver); 856 - } 857 - 858 - static void __exit mt9t031_mod_exit(void) 859 - { 860 - i2c_del_driver(&mt9t031_i2c_driver); 861 - } 862 - 863 - module_init(mt9t031_mod_init); 864 - module_exit(mt9t031_mod_exit); 853 + module_i2c_driver(mt9t031_i2c_driver); 865 854 866 855 MODULE_DESCRIPTION("Micron MT9T031 Camera driver"); 867 856 MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+1 -15
drivers/media/video/mt9t112.c
··· 1117 1117 .id_table = mt9t112_id, 1118 1118 }; 1119 1119 1120 - /************************************************************************ 1121 - module function 1122 - ************************************************************************/ 1123 - static int __init mt9t112_module_init(void) 1124 - { 1125 - return i2c_add_driver(&mt9t112_i2c_driver); 1126 - } 1127 - 1128 - static void __exit mt9t112_module_exit(void) 1129 - { 1130 - i2c_del_driver(&mt9t112_i2c_driver); 1131 - } 1132 - 1133 - module_init(mt9t112_module_init); 1134 - module_exit(mt9t112_module_exit); 1120 + module_i2c_driver(mt9t112_i2c_driver); 1135 1121 1136 1122 MODULE_DESCRIPTION("SoC Camera driver for mt9t112"); 1137 1123 MODULE_AUTHOR("Kuninori Morimoto");
+1 -12
drivers/media/video/mt9v011.c
··· 709 709 .id_table = mt9v011_id, 710 710 }; 711 711 712 - static __init int init_mt9v011(void) 713 - { 714 - return i2c_add_driver(&mt9v011_driver); 715 - } 716 - 717 - static __exit void exit_mt9v011(void) 718 - { 719 - i2c_del_driver(&mt9v011_driver); 720 - } 721 - 722 - module_init(init_mt9v011); 723 - module_exit(exit_mt9v011); 712 + module_i2c_driver(mt9v011_driver);
+1 -12
drivers/media/video/mt9v022.c
··· 872 872 .id_table = mt9v022_id, 873 873 }; 874 874 875 - static int __init mt9v022_mod_init(void) 876 - { 877 - return i2c_add_driver(&mt9v022_i2c_driver); 878 - } 879 - 880 - static void __exit mt9v022_mod_exit(void) 881 - { 882 - i2c_del_driver(&mt9v022_i2c_driver); 883 - } 884 - 885 - module_init(mt9v022_mod_init); 886 - module_exit(mt9v022_mod_exit); 875 + module_i2c_driver(mt9v022_i2c_driver); 887 876 888 877 MODULE_DESCRIPTION("Micron MT9V022 Camera driver"); 889 878 MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
+1 -12
drivers/media/video/mt9v032.c
··· 756 756 .id_table = mt9v032_id, 757 757 }; 758 758 759 - static int __init mt9v032_init(void) 760 - { 761 - return i2c_add_driver(&mt9v032_driver); 762 - } 763 - 764 - static void __exit mt9v032_exit(void) 765 - { 766 - i2c_del_driver(&mt9v032_driver); 767 - } 768 - 769 - module_init(mt9v032_init); 770 - module_exit(mt9v032_exit); 759 + module_i2c_driver(mt9v032_driver); 771 760 772 761 MODULE_DESCRIPTION("Aptina MT9V032 Camera driver"); 773 762 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+670 -548
drivers/media/video/mx2_camera.c
··· 3 3 * 4 4 * Copyright (C) 2008, Sascha Hauer, Pengutronix 5 5 * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography 6 + * Copyright (C) 2012, Javier Martin, Vista Silicon S.L. 6 7 * 7 8 * This program is free software; you can redistribute it and/or modify 8 9 * it under the terms of the GNU General Public License as published by ··· 19 18 #include <linux/dma-mapping.h> 20 19 #include <linux/errno.h> 21 20 #include <linux/fs.h> 21 + #include <linux/gcd.h> 22 22 #include <linux/interrupt.h> 23 23 #include <linux/kernel.h> 24 24 #include <linux/mm.h> ··· 32 30 33 31 #include <media/v4l2-common.h> 34 32 #include <media/v4l2-dev.h> 35 - #include <media/videobuf-core.h> 36 - #include <media/videobuf-dma-contig.h> 33 + #include <media/videobuf2-core.h> 34 + #include <media/videobuf2-dma-contig.h> 37 35 #include <media/soc_camera.h> 38 36 #include <media/soc_mediabus.h> 39 37 40 38 #include <linux/videodev2.h> 41 39 42 40 #include <mach/mx2_cam.h> 43 - #ifdef CONFIG_MACH_MX27 44 - #include <mach/dma-mx1-mx2.h> 45 - #endif 46 41 #include <mach/hardware.h> 47 42 48 43 #include <asm/dma.h> ··· 205 206 #define PRP_INTR_LBOVF (1 << 7) 206 207 #define PRP_INTR_CH2OVF (1 << 8) 207 208 208 - #define mx27_camera_emma(pcdev) (cpu_is_mx27() && pcdev->use_emma) 209 + /* Resizing registers */ 210 + #define PRP_RZ_VALID_TBL_LEN(x) ((x) << 24) 211 + #define PRP_RZ_VALID_BILINEAR (1 << 31) 209 212 210 213 #define MAX_VIDEO_MEM 16 214 + 215 + #define RESIZE_NUM_MIN 1 216 + #define RESIZE_NUM_MAX 20 217 + #define BC_COEF 3 218 + #define SZ_COEF (1 << BC_COEF) 219 + 220 + #define RESIZE_DIR_H 0 221 + #define RESIZE_DIR_V 1 222 + 223 + #define RESIZE_ALGO_BILINEAR 0 224 + #define RESIZE_ALGO_AVERAGING 1 211 225 212 226 struct mx2_prp_cfg { 213 227 int channel; ··· 231 219 u32 irq_flags; 232 220 }; 233 221 222 + /* prp resizing parameters */ 223 + struct emma_prp_resize { 224 + int algo; /* type of algorithm used */ 225 + int len; /* number of coefficients */ 226 + unsigned char s[RESIZE_NUM_MAX]; /* table of coefficients */ 227 + }; 228 + 234 229 /* prp configuration for a client-host fmt pair */ 235 230 struct mx2_fmt_cfg { 236 231 enum v4l2_mbus_pixelcode in_fmt; 237 232 u32 out_fmt; 238 233 struct mx2_prp_cfg cfg; 234 + }; 235 + 236 + enum mx2_buffer_state { 237 + MX2_STATE_QUEUED, 238 + MX2_STATE_ACTIVE, 239 + MX2_STATE_DONE, 240 + }; 241 + 242 + struct mx2_buf_internal { 243 + struct list_head queue; 244 + int bufnum; 245 + bool discard; 246 + }; 247 + 248 + /* buffer for one video frame */ 249 + struct mx2_buffer { 250 + /* common v4l buffer stuff -- must be first */ 251 + struct vb2_buffer vb; 252 + enum mx2_buffer_state state; 253 + struct mx2_buf_internal internal; 239 254 }; 240 255 241 256 struct mx2_camera_dev { ··· 281 242 282 243 struct list_head capture; 283 244 struct list_head active_bufs; 245 + struct list_head discard; 284 246 285 247 spinlock_t lock; 286 248 ··· 290 250 struct mx2_buffer *fb1_active; 291 251 struct mx2_buffer *fb2_active; 292 252 293 - int use_emma; 294 - 295 253 u32 csicr1; 296 254 255 + struct mx2_buf_internal buf_discard[2]; 297 256 void *discard_buffer; 298 257 dma_addr_t discard_buffer_dma; 299 258 size_t discard_size; 300 259 struct mx2_fmt_cfg *emma_prp; 260 + struct emma_prp_resize resizing[2]; 261 + unsigned int s_width, s_height; 301 262 u32 frame_count; 263 + struct vb2_alloc_ctx *alloc_ctx; 302 264 }; 303 265 304 - /* buffer for one video frame */ 305 - struct mx2_buffer { 306 - /* common v4l buffer stuff -- must be first */ 307 - struct videobuf_buffer vb; 308 - 309 - enum v4l2_mbus_pixelcode code; 310 - 311 - int bufnum; 312 - }; 266 + static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf) 267 + { 268 + return container_of(int_buf, struct mx2_buffer, internal); 269 + } 313 270 314 271 static struct mx2_fmt_cfg mx27_emma_prp_table[] = { 315 272 /* ··· 361 324 return &mx27_emma_prp_table[0]; 362 325 }; 363 326 327 + static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev, 328 + unsigned long phys, int bufnum) 329 + { 330 + struct mx2_fmt_cfg *prp = pcdev->emma_prp; 331 + 332 + if (prp->cfg.channel == 1) { 333 + writel(phys, pcdev->base_emma + 334 + PRP_DEST_RGB1_PTR + 4 * bufnum); 335 + } else { 336 + writel(phys, pcdev->base_emma + 337 + PRP_DEST_Y_PTR - 0x14 * bufnum); 338 + if (prp->out_fmt == V4L2_PIX_FMT_YUV420) { 339 + u32 imgsize = pcdev->icd->user_height * 340 + pcdev->icd->user_width; 341 + 342 + writel(phys + imgsize, pcdev->base_emma + 343 + PRP_DEST_CB_PTR - 0x14 * bufnum); 344 + writel(phys + ((5 * imgsize) / 4), pcdev->base_emma + 345 + PRP_DEST_CR_PTR - 0x14 * bufnum); 346 + } 347 + } 348 + } 349 + 364 350 static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) 365 351 { 366 352 unsigned long flags; 367 353 368 354 clk_disable(pcdev->clk_csi); 369 355 writel(0, pcdev->base_csi + CSICR1); 370 - if (mx27_camera_emma(pcdev)) { 356 + if (cpu_is_mx27()) { 371 357 writel(0, pcdev->base_emma + PRP_CNTL); 372 358 } else if (cpu_is_mx25()) { 373 359 spin_lock_irqsave(&pcdev->lock, flags); ··· 422 362 423 363 csicr1 = CSICR1_MCLKEN; 424 364 425 - if (mx27_camera_emma(pcdev)) { 365 + if (cpu_is_mx27()) { 426 366 csicr1 |= CSICR1_PRP_IF_EN | CSICR1_FCC | 427 367 CSICR1_RXFF_LEVEL(0); 428 368 } else if (cpu_is_mx27()) ··· 452 392 453 393 mx2_camera_deactivate(pcdev); 454 394 455 - if (pcdev->discard_buffer) { 456 - dma_free_coherent(ici->v4l2_dev.dev, pcdev->discard_size, 457 - pcdev->discard_buffer, 458 - pcdev->discard_buffer_dma); 459 - pcdev->discard_buffer = NULL; 460 - } 461 - 462 395 pcdev->icd = NULL; 463 396 } 464 - 465 - #ifdef CONFIG_MACH_MX27 466 - static void mx27_camera_dma_enable(struct mx2_camera_dev *pcdev) 467 - { 468 - u32 tmp; 469 - 470 - imx_dma_enable(pcdev->dma); 471 - 472 - tmp = readl(pcdev->base_csi + CSICR1); 473 - tmp |= CSICR1_RF_OR_INTEN; 474 - writel(tmp, pcdev->base_csi + CSICR1); 475 - } 476 - 477 - static irqreturn_t mx27_camera_irq(int irq_csi, void *data) 478 - { 479 - struct mx2_camera_dev *pcdev = data; 480 - u32 status = readl(pcdev->base_csi + CSISR); 481 - 482 - if (status & CSISR_SOF_INT && pcdev->active) { 483 - u32 tmp; 484 - 485 - tmp = readl(pcdev->base_csi + CSICR1); 486 - writel(tmp | CSICR1_CLR_RXFIFO, pcdev->base_csi + CSICR1); 487 - mx27_camera_dma_enable(pcdev); 488 - } 489 - 490 - writel(CSISR_SOF_INT | CSISR_RFF_OR_INT, pcdev->base_csi + CSISR); 491 - 492 - return IRQ_HANDLED; 493 - } 494 - #else 495 - static irqreturn_t mx27_camera_irq(int irq_csi, void *data) 496 - { 497 - return IRQ_NONE; 498 - } 499 - #endif /* CONFIG_MACH_MX27 */ 500 397 501 398 static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, 502 399 int state) 503 400 { 504 - struct videobuf_buffer *vb; 401 + struct vb2_buffer *vb; 505 402 struct mx2_buffer *buf; 506 403 struct mx2_buffer **fb_active = fb == 1 ? &pcdev->fb1_active : 507 404 &pcdev->fb2_active; ··· 471 454 goto out; 472 455 473 456 vb = &(*fb_active)->vb; 474 - dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 475 - vb, vb->baddr, vb->bsize); 457 + dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, 458 + vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 476 459 477 - vb->state = state; 478 - do_gettimeofday(&vb->ts); 479 - vb->field_count++; 480 - 481 - wake_up(&vb->done); 460 + do_gettimeofday(&vb->v4l2_buf.timestamp); 461 + vb->v4l2_buf.sequence++; 462 + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 482 463 483 464 if (list_empty(&pcdev->capture)) { 484 465 buf = NULL; 485 466 writel(0, pcdev->base_csi + fb_reg); 486 467 } else { 487 - buf = list_entry(pcdev->capture.next, struct mx2_buffer, 488 - vb.queue); 468 + buf = list_first_entry(&pcdev->capture, struct mx2_buffer, 469 + internal.queue); 489 470 vb = &buf->vb; 490 - list_del(&vb->queue); 491 - vb->state = VIDEOBUF_ACTIVE; 492 - writel(videobuf_to_dma_contig(vb), pcdev->base_csi + fb_reg); 471 + list_del(&buf->internal.queue); 472 + buf->state = MX2_STATE_ACTIVE; 473 + writel(vb2_dma_contig_plane_dma_addr(vb, 0), 474 + pcdev->base_csi + fb_reg); 493 475 } 494 476 495 477 *fb_active = buf; ··· 503 487 u32 status = readl(pcdev->base_csi + CSISR); 504 488 505 489 if (status & CSISR_DMA_TSF_FB1_INT) 506 - mx25_camera_frame_done(pcdev, 1, VIDEOBUF_DONE); 490 + mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE); 507 491 else if (status & CSISR_DMA_TSF_FB2_INT) 508 - mx25_camera_frame_done(pcdev, 2, VIDEOBUF_DONE); 492 + mx25_camera_frame_done(pcdev, 2, MX2_STATE_DONE); 509 493 510 494 /* FIXME: handle CSISR_RFF_OR_INT */ 511 495 ··· 517 501 /* 518 502 * Videobuf operations 519 503 */ 520 - static int mx2_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, 521 - unsigned int *size) 504 + static int mx2_videobuf_setup(struct vb2_queue *vq, 505 + const struct v4l2_format *fmt, 506 + unsigned int *count, unsigned int *num_planes, 507 + unsigned int sizes[], void *alloc_ctxs[]) 522 508 { 523 - struct soc_camera_device *icd = vq->priv_data; 509 + struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 510 + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 511 + struct mx2_camera_dev *pcdev = ici->priv; 524 512 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 525 513 icd->current_fmt->host_fmt); 526 514 527 - dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size); 515 + dev_dbg(icd->parent, "count=%d, size=%d\n", *count, sizes[0]); 516 + 517 + /* TODO: support for VIDIOC_CREATE_BUFS not ready */ 518 + if (fmt != NULL) 519 + return -ENOTTY; 528 520 529 521 if (bytes_per_line < 0) 530 522 return bytes_per_line; 531 523 532 - *size = bytes_per_line * icd->user_height; 524 + alloc_ctxs[0] = pcdev->alloc_ctx; 525 + 526 + sizes[0] = bytes_per_line * icd->user_height; 533 527 534 528 if (0 == *count) 535 529 *count = 32; 536 - if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) 537 - *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size; 530 + if (!*num_planes && 531 + sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024) 532 + *count = (MAX_VIDEO_MEM * 1024 * 1024) / sizes[0]; 533 + 534 + *num_planes = 1; 538 535 539 536 return 0; 540 537 } 541 538 542 - static void free_buffer(struct videobuf_queue *vq, struct mx2_buffer *buf) 539 + static int mx2_videobuf_prepare(struct vb2_buffer *vb) 543 540 { 544 - struct soc_camera_device *icd = vq->priv_data; 545 - struct videobuf_buffer *vb = &buf->vb; 546 - 547 - dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 548 - vb, vb->baddr, vb->bsize); 549 - 550 - /* 551 - * This waits until this buffer is out of danger, i.e., until it is no 552 - * longer in state VIDEOBUF_QUEUED or VIDEOBUF_ACTIVE 553 - */ 554 - videobuf_waiton(vq, vb, 0, 0); 555 - 556 - videobuf_dma_contig_free(vq, vb); 557 - dev_dbg(icd->parent, "%s freed\n", __func__); 558 - 559 - vb->state = VIDEOBUF_NEEDS_INIT; 560 - } 561 - 562 - static int mx2_videobuf_prepare(struct videobuf_queue *vq, 563 - struct videobuf_buffer *vb, enum v4l2_field field) 564 - { 565 - struct soc_camera_device *icd = vq->priv_data; 566 - struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); 541 + struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); 567 542 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 568 543 icd->current_fmt->host_fmt); 569 544 int ret = 0; 570 545 571 - dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 572 - vb, vb->baddr, vb->bsize); 546 + dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 547 + vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 573 548 574 549 if (bytes_per_line < 0) 575 550 return bytes_per_line; ··· 570 563 * This can be useful if you want to see if we actually fill 571 564 * the buffer with something 572 565 */ 573 - memset((void *)vb->baddr, 0xaa, vb->bsize); 566 + memset((void *)vb2_plane_vaddr(vb, 0), 567 + 0xaa, vb2_get_plane_payload(vb, 0)); 574 568 #endif 575 569 576 - if (buf->code != icd->current_fmt->code || 577 - vb->width != icd->user_width || 578 - vb->height != icd->user_height || 579 - vb->field != field) { 580 - buf->code = icd->current_fmt->code; 581 - vb->width = icd->user_width; 582 - vb->height = icd->user_height; 583 - vb->field = field; 584 - vb->state = VIDEOBUF_NEEDS_INIT; 585 - } 586 - 587 - vb->size = bytes_per_line * vb->height; 588 - if (vb->baddr && vb->bsize < vb->size) { 570 + vb2_set_plane_payload(vb, 0, bytes_per_line * icd->user_height); 571 + if (vb2_plane_vaddr(vb, 0) && 572 + vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { 589 573 ret = -EINVAL; 590 574 goto out; 591 575 } 592 576 593 - if (vb->state == VIDEOBUF_NEEDS_INIT) { 594 - ret = videobuf_iolock(vq, vb, NULL); 595 - if (ret) 596 - goto fail; 597 - 598 - vb->state = VIDEOBUF_PREPARED; 599 - } 600 - 601 577 return 0; 602 578 603 - fail: 604 - free_buffer(vq, buf); 605 579 out: 606 580 return ret; 607 581 } 608 582 609 - static void mx2_videobuf_queue(struct videobuf_queue *vq, 610 - struct videobuf_buffer *vb) 583 + static void mx2_videobuf_queue(struct vb2_buffer *vb) 611 584 { 612 - struct soc_camera_device *icd = vq->priv_data; 585 + struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); 613 586 struct soc_camera_host *ici = 614 587 to_soc_camera_host(icd->parent); 615 588 struct mx2_camera_dev *pcdev = ici->priv; 616 589 struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); 617 590 unsigned long flags; 618 591 619 - dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 620 - vb, vb->baddr, vb->bsize); 592 + dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 593 + vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 621 594 622 595 spin_lock_irqsave(&pcdev->lock, flags); 623 596 624 - vb->state = VIDEOBUF_QUEUED; 625 - list_add_tail(&vb->queue, &pcdev->capture); 597 + buf->state = MX2_STATE_QUEUED; 598 + list_add_tail(&buf->internal.queue, &pcdev->capture); 626 599 627 - if (mx27_camera_emma(pcdev)) { 628 - goto out; 629 - #ifdef CONFIG_MACH_MX27 630 - } else if (cpu_is_mx27()) { 631 - int ret; 632 - 633 - if (pcdev->active == NULL) { 634 - ret = imx_dma_setup_single(pcdev->dma, 635 - videobuf_to_dma_contig(vb), vb->size, 636 - (u32)pcdev->base_dma + 0x10, 637 - DMA_MODE_READ); 638 - if (ret) { 639 - vb->state = VIDEOBUF_ERROR; 640 - wake_up(&vb->done); 641 - goto out; 642 - } 643 - 644 - vb->state = VIDEOBUF_ACTIVE; 645 - pcdev->active = buf; 646 - } 647 - #endif 648 - } else { /* cpu_is_mx25() */ 600 + if (cpu_is_mx25()) { 649 601 u32 csicr3, dma_inten = 0; 650 602 651 603 if (pcdev->fb1_active == NULL) { 652 - writel(videobuf_to_dma_contig(vb), 604 + writel(vb2_dma_contig_plane_dma_addr(vb, 0), 653 605 pcdev->base_csi + CSIDMASA_FB1); 654 606 pcdev->fb1_active = buf; 655 607 dma_inten = CSICR1_FB1_DMA_INTEN; 656 608 } else if (pcdev->fb2_active == NULL) { 657 - writel(videobuf_to_dma_contig(vb), 609 + writel(vb2_dma_contig_plane_dma_addr(vb, 0), 658 610 pcdev->base_csi + CSIDMASA_FB2); 659 611 pcdev->fb2_active = buf; 660 612 dma_inten = CSICR1_FB2_DMA_INTEN; 661 613 } 662 614 663 615 if (dma_inten) { 664 - list_del(&vb->queue); 665 - vb->state = VIDEOBUF_ACTIVE; 616 + list_del(&buf->internal.queue); 617 + buf->state = MX2_STATE_ACTIVE; 666 618 667 619 csicr3 = readl(pcdev->base_csi + CSICR3); 668 620 ··· 640 674 } 641 675 } 642 676 643 - out: 644 677 spin_unlock_irqrestore(&pcdev->lock, flags); 645 678 } 646 679 647 - static void mx2_videobuf_release(struct videobuf_queue *vq, 648 - struct videobuf_buffer *vb) 680 + static void mx2_videobuf_release(struct vb2_buffer *vb) 649 681 { 650 - struct soc_camera_device *icd = vq->priv_data; 682 + struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); 651 683 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 652 684 struct mx2_camera_dev *pcdev = ici->priv; 653 685 struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); 654 686 unsigned long flags; 655 687 656 688 #ifdef DEBUG 657 - dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 658 - vb, vb->baddr, vb->bsize); 689 + dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 690 + vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 659 691 660 - switch (vb->state) { 661 - case VIDEOBUF_ACTIVE: 692 + switch (buf->state) { 693 + case MX2_STATE_ACTIVE: 662 694 dev_info(icd->parent, "%s (active)\n", __func__); 663 695 break; 664 - case VIDEOBUF_QUEUED: 696 + case MX2_STATE_QUEUED: 665 697 dev_info(icd->parent, "%s (queued)\n", __func__); 666 - break; 667 - case VIDEOBUF_PREPARED: 668 - dev_info(icd->parent, "%s (prepared)\n", __func__); 669 698 break; 670 699 default: 671 700 dev_info(icd->parent, "%s (unknown) %d\n", __func__, 672 - vb->state); 701 + buf->state); 673 702 break; 674 703 } 675 704 #endif ··· 678 717 * state. This requires a specific handling for each of the these DMA 679 718 * types. 680 719 */ 720 + 681 721 spin_lock_irqsave(&pcdev->lock, flags); 682 - if (vb->state == VIDEOBUF_QUEUED) { 683 - list_del(&vb->queue); 684 - vb->state = VIDEOBUF_ERROR; 685 - } else if (cpu_is_mx25() && vb->state == VIDEOBUF_ACTIVE) { 722 + if (cpu_is_mx25() && buf->state == MX2_STATE_ACTIVE) { 686 723 if (pcdev->fb1_active == buf) { 687 724 pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN; 688 725 writel(0, pcdev->base_csi + CSIDMASA_FB1); ··· 691 732 pcdev->fb2_active = NULL; 692 733 } 693 734 writel(pcdev->csicr1, pcdev->base_csi + CSICR1); 694 - vb->state = VIDEOBUF_ERROR; 695 735 } 696 736 spin_unlock_irqrestore(&pcdev->lock, flags); 697 - 698 - free_buffer(vq, buf); 699 737 } 700 738 701 - static struct videobuf_queue_ops mx2_videobuf_ops = { 702 - .buf_setup = mx2_videobuf_setup, 703 - .buf_prepare = mx2_videobuf_prepare, 704 - .buf_queue = mx2_videobuf_queue, 705 - .buf_release = mx2_videobuf_release, 739 + static void mx27_camera_emma_buf_init(struct soc_camera_device *icd, 740 + int bytesperline) 741 + { 742 + struct soc_camera_host *ici = 743 + to_soc_camera_host(icd->parent); 744 + struct mx2_camera_dev *pcdev = ici->priv; 745 + struct mx2_fmt_cfg *prp = pcdev->emma_prp; 746 + 747 + writel((pcdev->s_width << 16) | pcdev->s_height, 748 + pcdev->base_emma + PRP_SRC_FRAME_SIZE); 749 + writel(prp->cfg.src_pixel, 750 + pcdev->base_emma + PRP_SRC_PIXEL_FORMAT_CNTL); 751 + if (prp->cfg.channel == 1) { 752 + writel((icd->user_width << 16) | icd->user_height, 753 + pcdev->base_emma + PRP_CH1_OUT_IMAGE_SIZE); 754 + writel(bytesperline, 755 + pcdev->base_emma + PRP_DEST_CH1_LINE_STRIDE); 756 + writel(prp->cfg.ch1_pixel, 757 + pcdev->base_emma + PRP_CH1_PIXEL_FORMAT_CNTL); 758 + } else { /* channel 2 */ 759 + writel((icd->user_width << 16) | icd->user_height, 760 + pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE); 761 + } 762 + 763 + /* Enable interrupts */ 764 + writel(prp->cfg.irq_flags, pcdev->base_emma + PRP_INTR_CNTL); 765 + } 766 + 767 + static void mx2_prp_resize_commit(struct mx2_camera_dev *pcdev) 768 + { 769 + int dir; 770 + 771 + for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) { 772 + unsigned char *s = pcdev->resizing[dir].s; 773 + int len = pcdev->resizing[dir].len; 774 + unsigned int coeff[2] = {0, 0}; 775 + unsigned int valid = 0; 776 + int i; 777 + 778 + if (len == 0) 779 + continue; 780 + 781 + for (i = RESIZE_NUM_MAX - 1; i >= 0; i--) { 782 + int j; 783 + 784 + j = i > 9 ? 1 : 0; 785 + coeff[j] = (coeff[j] << BC_COEF) | 786 + (s[i] & (SZ_COEF - 1)); 787 + 788 + if (i == 5 || i == 15) 789 + coeff[j] <<= 1; 790 + 791 + valid = (valid << 1) | (s[i] >> BC_COEF); 792 + } 793 + 794 + valid |= PRP_RZ_VALID_TBL_LEN(len); 795 + 796 + if (pcdev->resizing[dir].algo == RESIZE_ALGO_BILINEAR) 797 + valid |= PRP_RZ_VALID_BILINEAR; 798 + 799 + if (pcdev->emma_prp->cfg.channel == 1) { 800 + if (dir == RESIZE_DIR_H) { 801 + writel(coeff[0], pcdev->base_emma + 802 + PRP_CH1_RZ_HORI_COEF1); 803 + writel(coeff[1], pcdev->base_emma + 804 + PRP_CH1_RZ_HORI_COEF2); 805 + writel(valid, pcdev->base_emma + 806 + PRP_CH1_RZ_HORI_VALID); 807 + } else { 808 + writel(coeff[0], pcdev->base_emma + 809 + PRP_CH1_RZ_VERT_COEF1); 810 + writel(coeff[1], pcdev->base_emma + 811 + PRP_CH1_RZ_VERT_COEF2); 812 + writel(valid, pcdev->base_emma + 813 + PRP_CH1_RZ_VERT_VALID); 814 + } 815 + } else { 816 + if (dir == RESIZE_DIR_H) { 817 + writel(coeff[0], pcdev->base_emma + 818 + PRP_CH2_RZ_HORI_COEF1); 819 + writel(coeff[1], pcdev->base_emma + 820 + PRP_CH2_RZ_HORI_COEF2); 821 + writel(valid, pcdev->base_emma + 822 + PRP_CH2_RZ_HORI_VALID); 823 + } else { 824 + writel(coeff[0], pcdev->base_emma + 825 + PRP_CH2_RZ_VERT_COEF1); 826 + writel(coeff[1], pcdev->base_emma + 827 + PRP_CH2_RZ_VERT_COEF2); 828 + writel(valid, pcdev->base_emma + 829 + PRP_CH2_RZ_VERT_VALID); 830 + } 831 + } 832 + } 833 + } 834 + 835 + static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) 836 + { 837 + struct soc_camera_device *icd = soc_camera_from_vb2q(q); 838 + struct soc_camera_host *ici = 839 + to_soc_camera_host(icd->parent); 840 + struct mx2_camera_dev *pcdev = ici->priv; 841 + struct mx2_fmt_cfg *prp = pcdev->emma_prp; 842 + struct vb2_buffer *vb; 843 + struct mx2_buffer *buf; 844 + unsigned long phys; 845 + int bytesperline; 846 + 847 + if (cpu_is_mx27()) { 848 + unsigned long flags; 849 + if (count < 2) 850 + return -EINVAL; 851 + 852 + spin_lock_irqsave(&pcdev->lock, flags); 853 + 854 + buf = list_first_entry(&pcdev->capture, struct mx2_buffer, 855 + internal.queue); 856 + buf->internal.bufnum = 0; 857 + vb = &buf->vb; 858 + buf->state = MX2_STATE_ACTIVE; 859 + 860 + phys = vb2_dma_contig_plane_dma_addr(vb, 0); 861 + mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); 862 + list_move_tail(pcdev->capture.next, &pcdev->active_bufs); 863 + 864 + buf = list_first_entry(&pcdev->capture, struct mx2_buffer, 865 + internal.queue); 866 + buf->internal.bufnum = 1; 867 + vb = &buf->vb; 868 + buf->state = MX2_STATE_ACTIVE; 869 + 870 + phys = vb2_dma_contig_plane_dma_addr(vb, 0); 871 + mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); 872 + list_move_tail(pcdev->capture.next, &pcdev->active_bufs); 873 + 874 + bytesperline = soc_mbus_bytes_per_line(icd->user_width, 875 + icd->current_fmt->host_fmt); 876 + if (bytesperline < 0) 877 + return bytesperline; 878 + 879 + /* 880 + * I didn't manage to properly enable/disable the prp 881 + * on a per frame basis during running transfers, 882 + * thus we allocate a buffer here and use it to 883 + * discard frames when no buffer is available. 884 + * Feel free to work on this ;) 885 + */ 886 + pcdev->discard_size = icd->user_height * bytesperline; 887 + pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev, 888 + pcdev->discard_size, &pcdev->discard_buffer_dma, 889 + GFP_KERNEL); 890 + if (!pcdev->discard_buffer) 891 + return -ENOMEM; 892 + 893 + pcdev->buf_discard[0].discard = true; 894 + list_add_tail(&pcdev->buf_discard[0].queue, 895 + &pcdev->discard); 896 + 897 + pcdev->buf_discard[1].discard = true; 898 + list_add_tail(&pcdev->buf_discard[1].queue, 899 + &pcdev->discard); 900 + 901 + mx2_prp_resize_commit(pcdev); 902 + 903 + mx27_camera_emma_buf_init(icd, bytesperline); 904 + 905 + if (prp->cfg.channel == 1) { 906 + writel(PRP_CNTL_CH1EN | 907 + PRP_CNTL_CSIEN | 908 + prp->cfg.in_fmt | 909 + prp->cfg.out_fmt | 910 + PRP_CNTL_CH1_LEN | 911 + PRP_CNTL_CH1BYP | 912 + PRP_CNTL_CH1_TSKIP(0) | 913 + PRP_CNTL_IN_TSKIP(0), 914 + pcdev->base_emma + PRP_CNTL); 915 + } else { 916 + writel(PRP_CNTL_CH2EN | 917 + PRP_CNTL_CSIEN | 918 + prp->cfg.in_fmt | 919 + prp->cfg.out_fmt | 920 + PRP_CNTL_CH2_LEN | 921 + PRP_CNTL_CH2_TSKIP(0) | 922 + PRP_CNTL_IN_TSKIP(0), 923 + pcdev->base_emma + PRP_CNTL); 924 + } 925 + spin_unlock_irqrestore(&pcdev->lock, flags); 926 + } 927 + 928 + return 0; 929 + } 930 + 931 + static int mx2_stop_streaming(struct vb2_queue *q) 932 + { 933 + struct soc_camera_device *icd = soc_camera_from_vb2q(q); 934 + struct soc_camera_host *ici = 935 + to_soc_camera_host(icd->parent); 936 + struct mx2_camera_dev *pcdev = ici->priv; 937 + struct mx2_fmt_cfg *prp = pcdev->emma_prp; 938 + unsigned long flags; 939 + void *b; 940 + u32 cntl; 941 + 942 + if (cpu_is_mx27()) { 943 + spin_lock_irqsave(&pcdev->lock, flags); 944 + 945 + cntl = readl(pcdev->base_emma + PRP_CNTL); 946 + if (prp->cfg.channel == 1) { 947 + writel(cntl & ~PRP_CNTL_CH1EN, 948 + pcdev->base_emma + PRP_CNTL); 949 + } else { 950 + writel(cntl & ~PRP_CNTL_CH2EN, 951 + pcdev->base_emma + PRP_CNTL); 952 + } 953 + INIT_LIST_HEAD(&pcdev->capture); 954 + INIT_LIST_HEAD(&pcdev->active_bufs); 955 + INIT_LIST_HEAD(&pcdev->discard); 956 + 957 + b = pcdev->discard_buffer; 958 + pcdev->discard_buffer = NULL; 959 + 960 + spin_unlock_irqrestore(&pcdev->lock, flags); 961 + 962 + dma_free_coherent(ici->v4l2_dev.dev, 963 + pcdev->discard_size, b, pcdev->discard_buffer_dma); 964 + } 965 + 966 + return 0; 967 + } 968 + 969 + static struct vb2_ops mx2_videobuf_ops = { 970 + .queue_setup = mx2_videobuf_setup, 971 + .buf_prepare = mx2_videobuf_prepare, 972 + .buf_queue = mx2_videobuf_queue, 973 + .buf_cleanup = mx2_videobuf_release, 974 + .start_streaming = mx2_start_streaming, 975 + .stop_streaming = mx2_stop_streaming, 706 976 }; 707 977 708 - static void mx2_camera_init_videobuf(struct videobuf_queue *q, 978 + static int mx2_camera_init_videobuf(struct vb2_queue *q, 709 979 struct soc_camera_device *icd) 710 980 { 711 - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 712 - struct mx2_camera_dev *pcdev = ici->priv; 981 + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 982 + q->io_modes = VB2_MMAP | VB2_USERPTR; 983 + q->drv_priv = icd; 984 + q->ops = &mx2_videobuf_ops; 985 + q->mem_ops = &vb2_dma_contig_memops; 986 + q->buf_struct_size = sizeof(struct mx2_buffer); 713 987 714 - videobuf_queue_dma_contig_init(q, &mx2_videobuf_ops, pcdev->dev, 715 - &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, 716 - V4L2_FIELD_NONE, sizeof(struct mx2_buffer), 717 - icd, &icd->video_lock); 988 + return vb2_queue_init(q); 718 989 } 719 990 720 991 #define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \ ··· 972 783 } 973 784 974 785 return -ETIMEDOUT; 975 - } 976 - 977 - static void mx27_camera_emma_buf_init(struct soc_camera_device *icd, 978 - int bytesperline) 979 - { 980 - struct soc_camera_host *ici = 981 - to_soc_camera_host(icd->parent); 982 - struct mx2_camera_dev *pcdev = ici->priv; 983 - struct mx2_fmt_cfg *prp = pcdev->emma_prp; 984 - u32 imgsize = pcdev->icd->user_height * pcdev->icd->user_width; 985 - 986 - if (prp->cfg.channel == 1) { 987 - writel(pcdev->discard_buffer_dma, 988 - pcdev->base_emma + PRP_DEST_RGB1_PTR); 989 - writel(pcdev->discard_buffer_dma, 990 - pcdev->base_emma + PRP_DEST_RGB2_PTR); 991 - 992 - writel(PRP_CNTL_CH1EN | 993 - PRP_CNTL_CSIEN | 994 - prp->cfg.in_fmt | 995 - prp->cfg.out_fmt | 996 - PRP_CNTL_CH1_LEN | 997 - PRP_CNTL_CH1BYP | 998 - PRP_CNTL_CH1_TSKIP(0) | 999 - PRP_CNTL_IN_TSKIP(0), 1000 - pcdev->base_emma + PRP_CNTL); 1001 - 1002 - writel((icd->user_width << 16) | icd->user_height, 1003 - pcdev->base_emma + PRP_SRC_FRAME_SIZE); 1004 - writel((icd->user_width << 16) | icd->user_height, 1005 - pcdev->base_emma + PRP_CH1_OUT_IMAGE_SIZE); 1006 - writel(bytesperline, 1007 - pcdev->base_emma + PRP_DEST_CH1_LINE_STRIDE); 1008 - writel(prp->cfg.src_pixel, 1009 - pcdev->base_emma + PRP_SRC_PIXEL_FORMAT_CNTL); 1010 - writel(prp->cfg.ch1_pixel, 1011 - pcdev->base_emma + PRP_CH1_PIXEL_FORMAT_CNTL); 1012 - } else { /* channel 2 */ 1013 - writel(pcdev->discard_buffer_dma, 1014 - pcdev->base_emma + PRP_DEST_Y_PTR); 1015 - writel(pcdev->discard_buffer_dma, 1016 - pcdev->base_emma + PRP_SOURCE_Y_PTR); 1017 - 1018 - if (prp->cfg.out_fmt == PRP_CNTL_CH2_OUT_YUV420) { 1019 - writel(pcdev->discard_buffer_dma + imgsize, 1020 - pcdev->base_emma + PRP_DEST_CB_PTR); 1021 - writel(pcdev->discard_buffer_dma + ((5 * imgsize) / 4), 1022 - pcdev->base_emma + PRP_DEST_CR_PTR); 1023 - writel(pcdev->discard_buffer_dma + imgsize, 1024 - pcdev->base_emma + PRP_SOURCE_CB_PTR); 1025 - writel(pcdev->discard_buffer_dma + ((5 * imgsize) / 4), 1026 - pcdev->base_emma + PRP_SOURCE_CR_PTR); 1027 - } 1028 - 1029 - writel(PRP_CNTL_CH2EN | 1030 - PRP_CNTL_CSIEN | 1031 - prp->cfg.in_fmt | 1032 - prp->cfg.out_fmt | 1033 - PRP_CNTL_CH2_LEN | 1034 - PRP_CNTL_CH2_TSKIP(0) | 1035 - PRP_CNTL_IN_TSKIP(0), 1036 - pcdev->base_emma + PRP_CNTL); 1037 - 1038 - writel((icd->user_width << 16) | icd->user_height, 1039 - pcdev->base_emma + PRP_SRC_FRAME_SIZE); 1040 - 1041 - writel((icd->user_width << 16) | icd->user_height, 1042 - pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE); 1043 - 1044 - writel(prp->cfg.src_pixel, 1045 - pcdev->base_emma + PRP_SRC_PIXEL_FORMAT_CNTL); 1046 - 1047 - } 1048 - 1049 - /* Enable interrupts */ 1050 - writel(prp->cfg.irq_flags, pcdev->base_emma + PRP_INTR_CNTL); 1051 786 } 1052 787 1053 788 static int mx2_camera_set_bus_param(struct soc_camera_device *icd) ··· 1052 939 if (bytesperline < 0) 1053 940 return bytesperline; 1054 941 1055 - if (mx27_camera_emma(pcdev)) { 942 + if (cpu_is_mx27()) { 1056 943 ret = mx27_camera_emma_prp_reset(pcdev); 1057 944 if (ret) 1058 945 return ret; 1059 - 1060 - if (pcdev->discard_buffer) 1061 - dma_free_coherent(ici->v4l2_dev.dev, 1062 - pcdev->discard_size, pcdev->discard_buffer, 1063 - pcdev->discard_buffer_dma); 1064 - 1065 - /* 1066 - * I didn't manage to properly enable/disable the prp 1067 - * on a per frame basis during running transfers, 1068 - * thus we allocate a buffer here and use it to 1069 - * discard frames when no buffer is available. 1070 - * Feel free to work on this ;) 1071 - */ 1072 - pcdev->discard_size = icd->user_height * bytesperline; 1073 - pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev, 1074 - pcdev->discard_size, &pcdev->discard_buffer_dma, 1075 - GFP_KERNEL); 1076 - if (!pcdev->discard_buffer) 1077 - return -ENOMEM; 1078 - 1079 - mx27_camera_emma_buf_init(icd, bytesperline); 1080 946 } else if (cpu_is_mx25()) { 1081 947 writel((bytesperline * icd->user_height) >> 2, 1082 948 pcdev->base_csi + CSIRXCNT); ··· 1144 1052 return formats; 1145 1053 } 1146 1054 1055 + static int mx2_emmaprp_resize(struct mx2_camera_dev *pcdev, 1056 + struct v4l2_mbus_framefmt *mf_in, 1057 + struct v4l2_pix_format *pix_out, bool apply) 1058 + { 1059 + int num, den; 1060 + unsigned long m; 1061 + int i, dir; 1062 + 1063 + for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) { 1064 + struct emma_prp_resize tmprsz; 1065 + unsigned char *s = tmprsz.s; 1066 + int len = 0; 1067 + int in, out; 1068 + 1069 + if (dir == RESIZE_DIR_H) { 1070 + in = mf_in->width; 1071 + out = pix_out->width; 1072 + } else { 1073 + in = mf_in->height; 1074 + out = pix_out->height; 1075 + } 1076 + 1077 + if (in < out) 1078 + return -EINVAL; 1079 + else if (in == out) 1080 + continue; 1081 + 1082 + /* Calculate ratio */ 1083 + m = gcd(in, out); 1084 + num = in / m; 1085 + den = out / m; 1086 + if (num > RESIZE_NUM_MAX) 1087 + return -EINVAL; 1088 + 1089 + if ((num >= 2 * den) && (den == 1) && 1090 + (num < 9) && (!(num & 0x01))) { 1091 + int sum = 0; 1092 + int j; 1093 + 1094 + /* Average scaling for >= 2:1 ratios */ 1095 + /* Support can be added for num >=9 and odd values */ 1096 + 1097 + tmprsz.algo = RESIZE_ALGO_AVERAGING; 1098 + len = num; 1099 + 1100 + for (i = 0; i < (len / 2); i++) 1101 + s[i] = 8; 1102 + 1103 + do { 1104 + for (i = 0; i < (len / 2); i++) { 1105 + s[i] = s[i] >> 1; 1106 + sum = 0; 1107 + for (j = 0; j < (len / 2); j++) 1108 + sum += s[j]; 1109 + if (sum == 4) 1110 + break; 1111 + } 1112 + } while (sum != 4); 1113 + 1114 + for (i = (len / 2); i < len; i++) 1115 + s[i] = s[len - i - 1]; 1116 + 1117 + s[len - 1] |= SZ_COEF; 1118 + } else { 1119 + /* bilinear scaling for < 2:1 ratios */ 1120 + int v; /* overflow counter */ 1121 + int coeff, nxt; /* table output */ 1122 + int in_pos_inc = 2 * den; 1123 + int out_pos = num; 1124 + int out_pos_inc = 2 * num; 1125 + int init_carry = num - den; 1126 + int carry = init_carry; 1127 + 1128 + tmprsz.algo = RESIZE_ALGO_BILINEAR; 1129 + v = den + in_pos_inc; 1130 + do { 1131 + coeff = v - out_pos; 1132 + out_pos += out_pos_inc; 1133 + carry += out_pos_inc; 1134 + for (nxt = 0; v < out_pos; nxt++) { 1135 + v += in_pos_inc; 1136 + carry -= in_pos_inc; 1137 + } 1138 + 1139 + if (len > RESIZE_NUM_MAX) 1140 + return -EINVAL; 1141 + 1142 + coeff = ((coeff << BC_COEF) + 1143 + (in_pos_inc >> 1)) / in_pos_inc; 1144 + 1145 + if (coeff >= (SZ_COEF - 1)) 1146 + coeff--; 1147 + 1148 + coeff |= SZ_COEF; 1149 + s[len] = (unsigned char)coeff; 1150 + len++; 1151 + 1152 + for (i = 1; i < nxt; i++) { 1153 + if (len >= RESIZE_NUM_MAX) 1154 + return -EINVAL; 1155 + s[len] = 0; 1156 + len++; 1157 + } 1158 + } while (carry != init_carry); 1159 + } 1160 + tmprsz.len = len; 1161 + if (dir == RESIZE_DIR_H) 1162 + mf_in->width = pix_out->width; 1163 + else 1164 + mf_in->height = pix_out->height; 1165 + 1166 + if (apply) 1167 + memcpy(&pcdev->resizing[dir], &tmprsz, sizeof(tmprsz)); 1168 + } 1169 + return 0; 1170 + } 1171 + 1147 1172 static int mx2_camera_set_fmt(struct soc_camera_device *icd, 1148 1173 struct v4l2_format *f) 1149 1174 { ··· 1271 1062 struct v4l2_pix_format *pix = &f->fmt.pix; 1272 1063 struct v4l2_mbus_framefmt mf; 1273 1064 int ret; 1065 + 1066 + dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n", 1067 + __func__, pix->width, pix->height); 1274 1068 1275 1069 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 1276 1070 if (!xlate) { ··· 1292 1080 if (ret < 0 && ret != -ENOIOCTLCMD) 1293 1081 return ret; 1294 1082 1083 + /* Store width and height returned by the sensor for resizing */ 1084 + pcdev->s_width = mf.width; 1085 + pcdev->s_height = mf.height; 1086 + dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n", 1087 + __func__, pcdev->s_width, pcdev->s_height); 1088 + 1089 + pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code, 1090 + xlate->host_fmt->fourcc); 1091 + 1092 + memset(pcdev->resizing, 0, sizeof(pcdev->resizing)); 1093 + if ((mf.width != pix->width || mf.height != pix->height) && 1094 + pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) { 1095 + if (mx2_emmaprp_resize(pcdev, &mf, pix, true) < 0) 1096 + dev_dbg(icd->parent, "%s: can't resize\n", __func__); 1097 + } 1098 + 1295 1099 if (mf.code != xlate->code) 1296 1100 return -EINVAL; 1297 1101 ··· 1317 1089 pix->colorspace = mf.colorspace; 1318 1090 icd->current_fmt = xlate; 1319 1091 1320 - if (mx27_camera_emma(pcdev)) 1321 - pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code, 1322 - xlate->host_fmt->fourcc); 1092 + dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n", 1093 + __func__, pix->width, pix->height); 1323 1094 1324 1095 return 0; 1325 1096 } ··· 1331 1104 struct v4l2_pix_format *pix = &f->fmt.pix; 1332 1105 struct v4l2_mbus_framefmt mf; 1333 1106 __u32 pixfmt = pix->pixelformat; 1107 + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1108 + struct mx2_camera_dev *pcdev = ici->priv; 1334 1109 unsigned int width_limit; 1335 1110 int ret; 1111 + 1112 + dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n", 1113 + __func__, pix->width, pix->height); 1336 1114 1337 1115 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1338 1116 if (pixfmt && !xlate) { ··· 1388 1156 if (ret < 0) 1389 1157 return ret; 1390 1158 1159 + dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n", 1160 + __func__, pcdev->s_width, pcdev->s_height); 1161 + 1162 + /* If the sensor does not support image size try PrP resizing */ 1163 + pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code, 1164 + xlate->host_fmt->fourcc); 1165 + 1166 + memset(pcdev->resizing, 0, sizeof(pcdev->resizing)); 1167 + if ((mf.width != pix->width || mf.height != pix->height) && 1168 + pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) { 1169 + if (mx2_emmaprp_resize(pcdev, &mf, pix, false) < 0) 1170 + dev_dbg(icd->parent, "%s: can't resize\n", __func__); 1171 + } 1172 + 1391 1173 if (mf.field == V4L2_FIELD_ANY) 1392 1174 mf.field = V4L2_FIELD_NONE; 1393 1175 /* ··· 1420 1174 pix->field = mf.field; 1421 1175 pix->colorspace = mf.colorspace; 1422 1176 1177 + dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n", 1178 + __func__, pix->width, pix->height); 1179 + 1423 1180 return 0; 1424 1181 } 1425 1182 ··· 1436 1187 return 0; 1437 1188 } 1438 1189 1439 - static int mx2_camera_reqbufs(struct soc_camera_device *icd, 1440 - struct v4l2_requestbuffers *p) 1441 - { 1442 - int i; 1443 - 1444 - for (i = 0; i < p->count; i++) { 1445 - struct mx2_buffer *buf = container_of(icd->vb_vidq.bufs[i], 1446 - struct mx2_buffer, vb); 1447 - INIT_LIST_HEAD(&buf->vb.queue); 1448 - } 1449 - 1450 - return 0; 1451 - } 1452 - 1453 - #ifdef CONFIG_MACH_MX27 1454 - static void mx27_camera_frame_done(struct mx2_camera_dev *pcdev, int state) 1455 - { 1456 - struct videobuf_buffer *vb; 1457 - struct mx2_buffer *buf; 1458 - unsigned long flags; 1459 - int ret; 1460 - 1461 - spin_lock_irqsave(&pcdev->lock, flags); 1462 - 1463 - if (!pcdev->active) { 1464 - dev_err(pcdev->dev, "%s called with no active buffer!\n", 1465 - __func__); 1466 - goto out; 1467 - } 1468 - 1469 - vb = &pcdev->active->vb; 1470 - buf = container_of(vb, struct mx2_buffer, vb); 1471 - WARN_ON(list_empty(&vb->queue)); 1472 - dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 1473 - vb, vb->baddr, vb->bsize); 1474 - 1475 - /* _init is used to debug races, see comment in pxa_camera_reqbufs() */ 1476 - list_del_init(&vb->queue); 1477 - vb->state = state; 1478 - do_gettimeofday(&vb->ts); 1479 - vb->field_count++; 1480 - 1481 - wake_up(&vb->done); 1482 - 1483 - if (list_empty(&pcdev->capture)) { 1484 - pcdev->active = NULL; 1485 - goto out; 1486 - } 1487 - 1488 - pcdev->active = list_entry(pcdev->capture.next, 1489 - struct mx2_buffer, vb.queue); 1490 - 1491 - vb = &pcdev->active->vb; 1492 - vb->state = VIDEOBUF_ACTIVE; 1493 - 1494 - ret = imx_dma_setup_single(pcdev->dma, videobuf_to_dma_contig(vb), 1495 - vb->size, (u32)pcdev->base_dma + 0x10, DMA_MODE_READ); 1496 - 1497 - if (ret) { 1498 - vb->state = VIDEOBUF_ERROR; 1499 - pcdev->active = NULL; 1500 - wake_up(&vb->done); 1501 - } 1502 - 1503 - out: 1504 - spin_unlock_irqrestore(&pcdev->lock, flags); 1505 - } 1506 - 1507 - static void mx27_camera_dma_err_callback(int channel, void *data, int err) 1508 - { 1509 - struct mx2_camera_dev *pcdev = data; 1510 - 1511 - mx27_camera_frame_done(pcdev, VIDEOBUF_ERROR); 1512 - } 1513 - 1514 - static void mx27_camera_dma_callback(int channel, void *data) 1515 - { 1516 - struct mx2_camera_dev *pcdev = data; 1517 - 1518 - mx27_camera_frame_done(pcdev, VIDEOBUF_DONE); 1519 - } 1520 - 1521 - #define DMA_REQ_CSI_RX 31 /* FIXME: Add this to a resource */ 1522 - 1523 - static int __devinit mx27_camera_dma_init(struct platform_device *pdev, 1524 - struct mx2_camera_dev *pcdev) 1525 - { 1526 - int err; 1527 - 1528 - pcdev->dma = imx_dma_request_by_prio("CSI RX DMA", DMA_PRIO_HIGH); 1529 - if (pcdev->dma < 0) { 1530 - dev_err(&pdev->dev, "%s failed to request DMA channel\n", 1531 - __func__); 1532 - return pcdev->dma; 1533 - } 1534 - 1535 - err = imx_dma_setup_handlers(pcdev->dma, mx27_camera_dma_callback, 1536 - mx27_camera_dma_err_callback, pcdev); 1537 - if (err) { 1538 - dev_err(&pdev->dev, "%s failed to set DMA callback\n", 1539 - __func__); 1540 - goto err_out; 1541 - } 1542 - 1543 - err = imx_dma_config_channel(pcdev->dma, 1544 - IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO, 1545 - IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, 1546 - DMA_REQ_CSI_RX, 1); 1547 - if (err) { 1548 - dev_err(&pdev->dev, "%s failed to config DMA channel\n", 1549 - __func__); 1550 - goto err_out; 1551 - } 1552 - 1553 - imx_dma_config_burstlen(pcdev->dma, 64); 1554 - 1555 - return 0; 1556 - 1557 - err_out: 1558 - imx_dma_free(pcdev->dma); 1559 - 1560 - return err; 1561 - } 1562 - #endif /* CONFIG_MACH_MX27 */ 1563 - 1564 1190 static unsigned int mx2_camera_poll(struct file *file, poll_table *pt) 1565 1191 { 1566 1192 struct soc_camera_device *icd = file->private_data; 1567 1193 1568 - return videobuf_poll_stream(file, &icd->vb_vidq, pt); 1194 + return vb2_poll(&icd->vb2_vidq, file, pt); 1569 1195 } 1570 1196 1571 1197 static struct soc_camera_host_ops mx2_soc_camera_host_ops = { ··· 1451 1327 .set_crop = mx2_camera_set_crop, 1452 1328 .get_formats = mx2_camera_get_formats, 1453 1329 .try_fmt = mx2_camera_try_fmt, 1454 - .init_videobuf = mx2_camera_init_videobuf, 1455 - .reqbufs = mx2_camera_reqbufs, 1330 + .init_videobuf2 = mx2_camera_init_videobuf, 1456 1331 .poll = mx2_camera_poll, 1457 1332 .querycap = mx2_camera_querycap, 1458 1333 .set_bus_param = mx2_camera_set_bus_param, 1459 1334 }; 1460 1335 1461 1336 static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, 1462 - int bufnum, int state) 1337 + int bufnum, bool err) 1463 1338 { 1464 - u32 imgsize = pcdev->icd->user_height * pcdev->icd->user_width; 1339 + #ifdef DEBUG 1465 1340 struct mx2_fmt_cfg *prp = pcdev->emma_prp; 1341 + #endif 1342 + struct mx2_buf_internal *ibuf; 1466 1343 struct mx2_buffer *buf; 1467 - struct videobuf_buffer *vb; 1344 + struct vb2_buffer *vb; 1468 1345 unsigned long phys; 1469 1346 1470 - if (!list_empty(&pcdev->active_bufs)) { 1471 - buf = list_entry(pcdev->active_bufs.next, 1472 - struct mx2_buffer, vb.queue); 1347 + ibuf = list_first_entry(&pcdev->active_bufs, struct mx2_buf_internal, 1348 + queue); 1473 1349 1474 - BUG_ON(buf->bufnum != bufnum); 1350 + BUG_ON(ibuf->bufnum != bufnum); 1351 + 1352 + if (ibuf->discard) { 1353 + /* 1354 + * Discard buffer must not be returned to user space. 1355 + * Just return it to the discard queue. 1356 + */ 1357 + list_move_tail(pcdev->active_bufs.next, &pcdev->discard); 1358 + } else { 1359 + buf = mx2_ibuf_to_buf(ibuf); 1475 1360 1476 1361 vb = &buf->vb; 1477 1362 #ifdef DEBUG 1478 - phys = videobuf_to_dma_contig(vb); 1363 + phys = vb2_dma_contig_plane_dma_addr(vb, 0); 1479 1364 if (prp->cfg.channel == 1) { 1480 1365 if (readl(pcdev->base_emma + PRP_DEST_RGB1_PTR + 1481 1366 4 * bufnum) != phys) { 1482 - dev_err(pcdev->dev, "%p != %p\n", phys, 1483 - readl(pcdev->base_emma + 1484 - PRP_DEST_RGB1_PTR + 1485 - 4 * bufnum)); 1367 + dev_err(pcdev->dev, "%lx != %x\n", phys, 1368 + readl(pcdev->base_emma + 1369 + PRP_DEST_RGB1_PTR + 4 * bufnum)); 1486 1370 } 1487 1371 } else { 1488 1372 if (readl(pcdev->base_emma + PRP_DEST_Y_PTR - 1489 1373 0x14 * bufnum) != phys) { 1490 - dev_err(pcdev->dev, "%p != %p\n", phys, 1491 - readl(pcdev->base_emma + 1492 - PRP_DEST_Y_PTR - 1493 - 0x14 * bufnum)); 1374 + dev_err(pcdev->dev, "%lx != %x\n", phys, 1375 + readl(pcdev->base_emma + 1376 + PRP_DEST_Y_PTR - 0x14 * bufnum)); 1494 1377 } 1495 1378 } 1496 1379 #endif 1497 - dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, 1498 - vb->baddr, vb->bsize); 1380 + dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, vb, 1381 + vb2_plane_vaddr(vb, 0), 1382 + vb2_get_plane_payload(vb, 0)); 1499 1383 1500 - list_del(&vb->queue); 1501 - vb->state = state; 1502 - do_gettimeofday(&vb->ts); 1503 - vb->field_count = pcdev->frame_count * 2; 1504 - pcdev->frame_count++; 1505 - 1506 - wake_up(&vb->done); 1384 + list_del_init(&buf->internal.queue); 1385 + do_gettimeofday(&vb->v4l2_buf.timestamp); 1386 + vb->v4l2_buf.sequence = pcdev->frame_count; 1387 + if (err) 1388 + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); 1389 + else 1390 + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 1507 1391 } 1508 1392 1393 + pcdev->frame_count++; 1394 + 1509 1395 if (list_empty(&pcdev->capture)) { 1510 - if (prp->cfg.channel == 1) { 1511 - writel(pcdev->discard_buffer_dma, pcdev->base_emma + 1512 - PRP_DEST_RGB1_PTR + 4 * bufnum); 1513 - } else { 1514 - writel(pcdev->discard_buffer_dma, pcdev->base_emma + 1515 - PRP_DEST_Y_PTR - 1516 - 0x14 * bufnum); 1517 - if (prp->out_fmt == V4L2_PIX_FMT_YUV420) { 1518 - writel(pcdev->discard_buffer_dma + imgsize, 1519 - pcdev->base_emma + PRP_DEST_CB_PTR - 1520 - 0x14 * bufnum); 1521 - writel(pcdev->discard_buffer_dma + 1522 - ((5 * imgsize) / 4), pcdev->base_emma + 1523 - PRP_DEST_CR_PTR - 0x14 * bufnum); 1524 - } 1396 + if (list_empty(&pcdev->discard)) { 1397 + dev_warn(pcdev->dev, "%s: trying to access empty discard list\n", 1398 + __func__); 1399 + return; 1525 1400 } 1401 + 1402 + ibuf = list_first_entry(&pcdev->discard, 1403 + struct mx2_buf_internal, queue); 1404 + ibuf->bufnum = bufnum; 1405 + 1406 + list_move_tail(pcdev->discard.next, &pcdev->active_bufs); 1407 + mx27_update_emma_buf(pcdev, pcdev->discard_buffer_dma, bufnum); 1526 1408 return; 1527 1409 } 1528 1410 1529 - buf = list_entry(pcdev->capture.next, 1530 - struct mx2_buffer, vb.queue); 1411 + buf = list_first_entry(&pcdev->capture, struct mx2_buffer, 1412 + internal.queue); 1531 1413 1532 - buf->bufnum = !bufnum; 1414 + buf->internal.bufnum = bufnum; 1533 1415 1534 1416 list_move_tail(pcdev->capture.next, &pcdev->active_bufs); 1535 1417 1536 1418 vb = &buf->vb; 1537 - vb->state = VIDEOBUF_ACTIVE; 1419 + buf->state = MX2_STATE_ACTIVE; 1538 1420 1539 - phys = videobuf_to_dma_contig(vb); 1540 - if (prp->cfg.channel == 1) { 1541 - writel(phys, pcdev->base_emma + PRP_DEST_RGB1_PTR + 4 * bufnum); 1542 - } else { 1543 - writel(phys, pcdev->base_emma + 1544 - PRP_DEST_Y_PTR - 0x14 * bufnum); 1545 - if (prp->cfg.out_fmt == PRP_CNTL_CH2_OUT_YUV420) { 1546 - writel(phys + imgsize, pcdev->base_emma + 1547 - PRP_DEST_CB_PTR - 0x14 * bufnum); 1548 - writel(phys + ((5 * imgsize) / 4), pcdev->base_emma + 1549 - PRP_DEST_CR_PTR - 0x14 * bufnum); 1550 - } 1551 - } 1421 + phys = vb2_dma_contig_plane_dma_addr(vb, 0); 1422 + mx27_update_emma_buf(pcdev, phys, bufnum); 1552 1423 } 1553 1424 1554 1425 static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) 1555 1426 { 1556 1427 struct mx2_camera_dev *pcdev = data; 1557 1428 unsigned int status = readl(pcdev->base_emma + PRP_INTRSTATUS); 1558 - struct mx2_buffer *buf; 1429 + struct mx2_buf_internal *ibuf; 1430 + 1431 + spin_lock(&pcdev->lock); 1432 + 1433 + if (list_empty(&pcdev->active_bufs)) { 1434 + dev_warn(pcdev->dev, "%s: called while active list is empty\n", 1435 + __func__); 1436 + 1437 + if (!status) { 1438 + spin_unlock(&pcdev->lock); 1439 + return IRQ_NONE; 1440 + } 1441 + } 1559 1442 1560 1443 if (status & (1 << 7)) { /* overflow */ 1561 - u32 cntl; 1562 - /* 1563 - * We only disable channel 1 here since this is the only 1564 - * enabled channel 1565 - * 1566 - * FIXME: the correct DMA overflow handling should be resetting 1567 - * the buffer, returning an error frame, and continuing with 1568 - * the next one. 1569 - */ 1570 - cntl = readl(pcdev->base_emma + PRP_CNTL); 1444 + u32 cntl = readl(pcdev->base_emma + PRP_CNTL); 1571 1445 writel(cntl & ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN), 1572 1446 pcdev->base_emma + PRP_CNTL); 1573 1447 writel(cntl, pcdev->base_emma + PRP_CNTL); 1574 - } 1575 - if ((((status & (3 << 5)) == (3 << 5)) || 1576 - ((status & (3 << 3)) == (3 << 3))) 1577 - && !list_empty(&pcdev->active_bufs)) { 1448 + 1449 + ibuf = list_first_entry(&pcdev->active_bufs, 1450 + struct mx2_buf_internal, queue); 1451 + mx27_camera_frame_done_emma(pcdev, 1452 + ibuf->bufnum, true); 1453 + 1454 + status &= ~(1 << 7); 1455 + } else if (((status & (3 << 5)) == (3 << 5)) || 1456 + ((status & (3 << 3)) == (3 << 3))) { 1578 1457 /* 1579 1458 * Both buffers have triggered, process the one we're expecting 1580 1459 * to first 1581 1460 */ 1582 - buf = list_entry(pcdev->active_bufs.next, 1583 - struct mx2_buffer, vb.queue); 1584 - mx27_camera_frame_done_emma(pcdev, buf->bufnum, VIDEOBUF_DONE); 1585 - status &= ~(1 << (6 - buf->bufnum)); /* mark processed */ 1461 + ibuf = list_first_entry(&pcdev->active_bufs, 1462 + struct mx2_buf_internal, queue); 1463 + mx27_camera_frame_done_emma(pcdev, ibuf->bufnum, false); 1464 + status &= ~(1 << (6 - ibuf->bufnum)); /* mark processed */ 1465 + } else if ((status & (1 << 6)) || (status & (1 << 4))) { 1466 + mx27_camera_frame_done_emma(pcdev, 0, false); 1467 + } else if ((status & (1 << 5)) || (status & (1 << 3))) { 1468 + mx27_camera_frame_done_emma(pcdev, 1, false); 1586 1469 } 1587 - if ((status & (1 << 6)) || (status & (1 << 4))) 1588 - mx27_camera_frame_done_emma(pcdev, 0, VIDEOBUF_DONE); 1589 - if ((status & (1 << 5)) || (status & (1 << 3))) 1590 - mx27_camera_frame_done_emma(pcdev, 1, VIDEOBUF_DONE); 1591 1470 1471 + spin_unlock(&pcdev->lock); 1592 1472 writel(status, pcdev->base_emma + PRP_INTRSTATUS); 1593 1473 1594 1474 return IRQ_HANDLED; ··· 1655 1527 struct resource *res_csi, *res_emma; 1656 1528 void __iomem *base_csi; 1657 1529 int irq_csi, irq_emma; 1658 - irq_handler_t mx2_cam_irq_handler = cpu_is_mx25() ? mx25_camera_irq 1659 - : mx27_camera_irq; 1660 1530 int err = 0; 1661 1531 1662 1532 dev_dbg(&pdev->dev, "initialising\n"); ··· 1676 1550 1677 1551 pcdev->clk_csi = clk_get(&pdev->dev, NULL); 1678 1552 if (IS_ERR(pcdev->clk_csi)) { 1553 + dev_err(&pdev->dev, "Could not get csi clock\n"); 1679 1554 err = PTR_ERR(pcdev->clk_csi); 1680 1555 goto exit_kfree; 1681 1556 } 1682 - 1683 - dev_dbg(&pdev->dev, "Camera clock frequency: %ld\n", 1684 - clk_get_rate(pcdev->clk_csi)); 1685 - 1686 - /* Initialize DMA */ 1687 - #ifdef CONFIG_MACH_MX27 1688 - if (cpu_is_mx27()) { 1689 - err = mx27_camera_dma_init(pdev, pcdev); 1690 - if (err) 1691 - goto exit_clk_put; 1692 - } 1693 - #endif /* CONFIG_MACH_MX27 */ 1694 1557 1695 1558 pcdev->res_csi = res_csi; 1696 1559 pcdev->pdata = pdev->dev.platform_data; ··· 1700 1585 1701 1586 INIT_LIST_HEAD(&pcdev->capture); 1702 1587 INIT_LIST_HEAD(&pcdev->active_bufs); 1588 + INIT_LIST_HEAD(&pcdev->discard); 1703 1589 spin_lock_init(&pcdev->lock); 1704 1590 1705 1591 /* ··· 1722 1606 pcdev->base_dma = res_csi->start; 1723 1607 pcdev->dev = &pdev->dev; 1724 1608 1725 - err = request_irq(pcdev->irq_csi, mx2_cam_irq_handler, 0, 1726 - MX2_CAM_DRV_NAME, pcdev); 1727 - if (err) { 1728 - dev_err(pcdev->dev, "Camera interrupt register failed \n"); 1729 - goto exit_iounmap; 1609 + if (cpu_is_mx25()) { 1610 + err = request_irq(pcdev->irq_csi, mx25_camera_irq, 0, 1611 + MX2_CAM_DRV_NAME, pcdev); 1612 + if (err) { 1613 + dev_err(pcdev->dev, "Camera interrupt register failed \n"); 1614 + goto exit_iounmap; 1615 + } 1730 1616 } 1731 1617 1732 1618 if (cpu_is_mx27()) { ··· 1736 1618 res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1737 1619 irq_emma = platform_get_irq(pdev, 1); 1738 1620 1739 - if (res_emma && irq_emma >= 0) { 1740 - dev_info(&pdev->dev, "Using EMMA\n"); 1741 - pcdev->use_emma = 1; 1742 - pcdev->res_emma = res_emma; 1743 - pcdev->irq_emma = irq_emma; 1744 - if (mx27_camera_emma_init(pcdev)) 1745 - goto exit_free_irq; 1621 + if (!res_emma || !irq_emma) { 1622 + dev_err(&pdev->dev, "no EMMA resources\n"); 1623 + goto exit_free_irq; 1746 1624 } 1625 + 1626 + pcdev->res_emma = res_emma; 1627 + pcdev->irq_emma = irq_emma; 1628 + if (mx27_camera_emma_init(pcdev)) 1629 + goto exit_free_irq; 1747 1630 } 1748 1631 1749 1632 pcdev->soc_host.drv_name = MX2_CAM_DRV_NAME, ··· 1752 1633 pcdev->soc_host.priv = pcdev; 1753 1634 pcdev->soc_host.v4l2_dev.dev = &pdev->dev; 1754 1635 pcdev->soc_host.nr = pdev->id; 1636 + 1637 + pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 1638 + if (IS_ERR(pcdev->alloc_ctx)) { 1639 + err = PTR_ERR(pcdev->alloc_ctx); 1640 + goto eallocctx; 1641 + } 1755 1642 err = soc_camera_host_register(&pcdev->soc_host); 1756 1643 if (err) 1757 1644 goto exit_free_emma; ··· 1768 1643 return 0; 1769 1644 1770 1645 exit_free_emma: 1771 - if (mx27_camera_emma(pcdev)) { 1646 + vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 1647 + eallocctx: 1648 + if (cpu_is_mx27()) { 1772 1649 free_irq(pcdev->irq_emma, pcdev); 1773 1650 clk_disable(pcdev->clk_emma); 1774 1651 clk_put(pcdev->clk_emma); 1775 1652 iounmap(pcdev->base_emma); 1776 - release_mem_region(res_emma->start, resource_size(res_emma)); 1653 + release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma)); 1777 1654 } 1778 1655 exit_free_irq: 1779 - free_irq(pcdev->irq_csi, pcdev); 1656 + if (cpu_is_mx25()) 1657 + free_irq(pcdev->irq_csi, pcdev); 1780 1658 exit_iounmap: 1781 1659 iounmap(base_csi); 1782 1660 exit_release: 1783 1661 release_mem_region(res_csi->start, resource_size(res_csi)); 1784 1662 exit_dma_free: 1785 - #ifdef CONFIG_MACH_MX27 1786 - if (cpu_is_mx27()) 1787 - imx_dma_free(pcdev->dma); 1788 - exit_clk_put: 1789 1663 clk_put(pcdev->clk_csi); 1790 - #endif /* CONFIG_MACH_MX27 */ 1791 1664 exit_kfree: 1792 1665 kfree(pcdev); 1793 1666 exit: ··· 1800 1677 struct resource *res; 1801 1678 1802 1679 clk_put(pcdev->clk_csi); 1803 - #ifdef CONFIG_MACH_MX27 1680 + if (cpu_is_mx25()) 1681 + free_irq(pcdev->irq_csi, pcdev); 1804 1682 if (cpu_is_mx27()) 1805 - imx_dma_free(pcdev->dma); 1806 - #endif /* CONFIG_MACH_MX27 */ 1807 - free_irq(pcdev->irq_csi, pcdev); 1808 - if (mx27_camera_emma(pcdev)) 1809 1683 free_irq(pcdev->irq_emma, pcdev); 1810 1684 1811 1685 soc_camera_host_unregister(&pcdev->soc_host); 1812 1686 1687 + vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 1688 + 1813 1689 iounmap(pcdev->base_csi); 1814 1690 1815 - if (mx27_camera_emma(pcdev)) { 1691 + if (cpu_is_mx27()) { 1816 1692 clk_disable(pcdev->clk_emma); 1817 1693 clk_put(pcdev->clk_emma); 1818 1694 iounmap(pcdev->base_emma);
+1008
drivers/media/video/mx2_emmaprp.c
··· 1 + /* 2 + * Support eMMa-PrP through mem2mem framework. 3 + * 4 + * eMMa-PrP is a piece of HW that allows fetching buffers 5 + * from one memory location and do several operations on 6 + * them such as scaling or format conversion giving, as a result 7 + * a new processed buffer in another memory location. 8 + * 9 + * Based on mem2mem_testdev.c by Pawel Osciak. 10 + * 11 + * Copyright (c) 2011 Vista Silicon S.L. 12 + * Javier Martin <javier.martin@vista-silicon.com> 13 + * 14 + * This program is free software; you can redistribute it and/or modify 15 + * it under the terms of the GNU General Public License as published by the 16 + * Free Software Foundation; either version 2 of the 17 + * License, or (at your option) any later version 18 + */ 19 + #include <linux/module.h> 20 + #include <linux/clk.h> 21 + #include <linux/slab.h> 22 + #include <linux/interrupt.h> 23 + #include <linux/io.h> 24 + 25 + #include <linux/platform_device.h> 26 + #include <media/v4l2-mem2mem.h> 27 + #include <media/v4l2-device.h> 28 + #include <media/v4l2-ioctl.h> 29 + #include <media/videobuf2-dma-contig.h> 30 + #include <asm/sizes.h> 31 + 32 + #define EMMAPRP_MODULE_NAME "mem2mem-emmaprp" 33 + 34 + MODULE_DESCRIPTION("Mem-to-mem device which supports eMMa-PrP present in mx2 SoCs"); 35 + MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com"); 36 + MODULE_LICENSE("GPL"); 37 + MODULE_VERSION("0.0.1"); 38 + 39 + static bool debug; 40 + module_param(debug, bool, 0644); 41 + 42 + #define MIN_W 32 43 + #define MIN_H 32 44 + #define MAX_W 2040 45 + #define MAX_H 2046 46 + 47 + #define S_ALIGN 1 /* multiple of 2 */ 48 + #define W_ALIGN_YUV420 3 /* multiple of 8 */ 49 + #define W_ALIGN_OTHERS 2 /* multiple of 4 */ 50 + #define H_ALIGN 1 /* multiple of 2 */ 51 + 52 + /* Flags that indicate a format can be used for capture/output */ 53 + #define MEM2MEM_CAPTURE (1 << 0) 54 + #define MEM2MEM_OUTPUT (1 << 1) 55 + 56 + #define MEM2MEM_NAME "m2m-emmaprp" 57 + 58 + /* In bytes, per queue */ 59 + #define MEM2MEM_VID_MEM_LIMIT SZ_16M 60 + 61 + #define dprintk(dev, fmt, arg...) \ 62 + v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg) 63 + 64 + /* EMMA PrP */ 65 + #define PRP_CNTL 0x00 66 + #define PRP_INTR_CNTL 0x04 67 + #define PRP_INTRSTATUS 0x08 68 + #define PRP_SOURCE_Y_PTR 0x0c 69 + #define PRP_SOURCE_CB_PTR 0x10 70 + #define PRP_SOURCE_CR_PTR 0x14 71 + #define PRP_DEST_RGB1_PTR 0x18 72 + #define PRP_DEST_RGB2_PTR 0x1c 73 + #define PRP_DEST_Y_PTR 0x20 74 + #define PRP_DEST_CB_PTR 0x24 75 + #define PRP_DEST_CR_PTR 0x28 76 + #define PRP_SRC_FRAME_SIZE 0x2c 77 + #define PRP_DEST_CH1_LINE_STRIDE 0x30 78 + #define PRP_SRC_PIXEL_FORMAT_CNTL 0x34 79 + #define PRP_CH1_PIXEL_FORMAT_CNTL 0x38 80 + #define PRP_CH1_OUT_IMAGE_SIZE 0x3c 81 + #define PRP_CH2_OUT_IMAGE_SIZE 0x40 82 + #define PRP_SRC_LINE_STRIDE 0x44 83 + #define PRP_CSC_COEF_012 0x48 84 + #define PRP_CSC_COEF_345 0x4c 85 + #define PRP_CSC_COEF_678 0x50 86 + #define PRP_CH1_RZ_HORI_COEF1 0x54 87 + #define PRP_CH1_RZ_HORI_COEF2 0x58 88 + #define PRP_CH1_RZ_HORI_VALID 0x5c 89 + #define PRP_CH1_RZ_VERT_COEF1 0x60 90 + #define PRP_CH1_RZ_VERT_COEF2 0x64 91 + #define PRP_CH1_RZ_VERT_VALID 0x68 92 + #define PRP_CH2_RZ_HORI_COEF1 0x6c 93 + #define PRP_CH2_RZ_HORI_COEF2 0x70 94 + #define PRP_CH2_RZ_HORI_VALID 0x74 95 + #define PRP_CH2_RZ_VERT_COEF1 0x78 96 + #define PRP_CH2_RZ_VERT_COEF2 0x7c 97 + #define PRP_CH2_RZ_VERT_VALID 0x80 98 + 99 + #define PRP_CNTL_CH1EN (1 << 0) 100 + #define PRP_CNTL_CH2EN (1 << 1) 101 + #define PRP_CNTL_CSIEN (1 << 2) 102 + #define PRP_CNTL_DATA_IN_YUV420 (0 << 3) 103 + #define PRP_CNTL_DATA_IN_YUV422 (1 << 3) 104 + #define PRP_CNTL_DATA_IN_RGB16 (2 << 3) 105 + #define PRP_CNTL_DATA_IN_RGB32 (3 << 3) 106 + #define PRP_CNTL_CH1_OUT_RGB8 (0 << 5) 107 + #define PRP_CNTL_CH1_OUT_RGB16 (1 << 5) 108 + #define PRP_CNTL_CH1_OUT_RGB32 (2 << 5) 109 + #define PRP_CNTL_CH1_OUT_YUV422 (3 << 5) 110 + #define PRP_CNTL_CH2_OUT_YUV420 (0 << 7) 111 + #define PRP_CNTL_CH2_OUT_YUV422 (1 << 7) 112 + #define PRP_CNTL_CH2_OUT_YUV444 (2 << 7) 113 + #define PRP_CNTL_CH1_LEN (1 << 9) 114 + #define PRP_CNTL_CH2_LEN (1 << 10) 115 + #define PRP_CNTL_SKIP_FRAME (1 << 11) 116 + #define PRP_CNTL_SWRST (1 << 12) 117 + #define PRP_CNTL_CLKEN (1 << 13) 118 + #define PRP_CNTL_WEN (1 << 14) 119 + #define PRP_CNTL_CH1BYP (1 << 15) 120 + #define PRP_CNTL_IN_TSKIP(x) ((x) << 16) 121 + #define PRP_CNTL_CH1_TSKIP(x) ((x) << 19) 122 + #define PRP_CNTL_CH2_TSKIP(x) ((x) << 22) 123 + #define PRP_CNTL_INPUT_FIFO_LEVEL(x) ((x) << 25) 124 + #define PRP_CNTL_RZ_FIFO_LEVEL(x) ((x) << 27) 125 + #define PRP_CNTL_CH2B1EN (1 << 29) 126 + #define PRP_CNTL_CH2B2EN (1 << 30) 127 + #define PRP_CNTL_CH2FEN (1 << 31) 128 + 129 + #define PRP_SIZE_HEIGHT(x) (x) 130 + #define PRP_SIZE_WIDTH(x) ((x) << 16) 131 + 132 + /* IRQ Enable and status register */ 133 + #define PRP_INTR_RDERR (1 << 0) 134 + #define PRP_INTR_CH1WERR (1 << 1) 135 + #define PRP_INTR_CH2WERR (1 << 2) 136 + #define PRP_INTR_CH1FC (1 << 3) 137 + #define PRP_INTR_CH2FC (1 << 5) 138 + #define PRP_INTR_LBOVF (1 << 7) 139 + #define PRP_INTR_CH2OVF (1 << 8) 140 + 141 + #define PRP_INTR_ST_RDERR (1 << 0) 142 + #define PRP_INTR_ST_CH1WERR (1 << 1) 143 + #define PRP_INTR_ST_CH2WERR (1 << 2) 144 + #define PRP_INTR_ST_CH2B2CI (1 << 3) 145 + #define PRP_INTR_ST_CH2B1CI (1 << 4) 146 + #define PRP_INTR_ST_CH1B2CI (1 << 5) 147 + #define PRP_INTR_ST_CH1B1CI (1 << 6) 148 + #define PRP_INTR_ST_LBOVF (1 << 7) 149 + #define PRP_INTR_ST_CH2OVF (1 << 8) 150 + 151 + struct emmaprp_fmt { 152 + char *name; 153 + u32 fourcc; 154 + /* Types the format can be used for */ 155 + u32 types; 156 + }; 157 + 158 + static struct emmaprp_fmt formats[] = { 159 + { 160 + .name = "YUV 4:2:0 Planar", 161 + .fourcc = V4L2_PIX_FMT_YUV420, 162 + .types = MEM2MEM_CAPTURE, 163 + }, 164 + { 165 + .name = "4:2:2, packed, YUYV", 166 + .fourcc = V4L2_PIX_FMT_YUYV, 167 + .types = MEM2MEM_OUTPUT, 168 + }, 169 + }; 170 + 171 + /* Per-queue, driver-specific private data */ 172 + struct emmaprp_q_data { 173 + unsigned int width; 174 + unsigned int height; 175 + unsigned int sizeimage; 176 + struct emmaprp_fmt *fmt; 177 + }; 178 + 179 + enum { 180 + V4L2_M2M_SRC = 0, 181 + V4L2_M2M_DST = 1, 182 + }; 183 + 184 + #define NUM_FORMATS ARRAY_SIZE(formats) 185 + 186 + static struct emmaprp_fmt *find_format(struct v4l2_format *f) 187 + { 188 + struct emmaprp_fmt *fmt; 189 + unsigned int k; 190 + 191 + for (k = 0; k < NUM_FORMATS; k++) { 192 + fmt = &formats[k]; 193 + if (fmt->fourcc == f->fmt.pix.pixelformat) 194 + break; 195 + } 196 + 197 + if (k == NUM_FORMATS) 198 + return NULL; 199 + 200 + return &formats[k]; 201 + } 202 + 203 + struct emmaprp_dev { 204 + struct v4l2_device v4l2_dev; 205 + struct video_device *vfd; 206 + 207 + struct mutex dev_mutex; 208 + spinlock_t irqlock; 209 + 210 + int irq_emma; 211 + void __iomem *base_emma; 212 + struct clk *clk_emma; 213 + struct resource *res_emma; 214 + 215 + struct v4l2_m2m_dev *m2m_dev; 216 + struct vb2_alloc_ctx *alloc_ctx; 217 + }; 218 + 219 + struct emmaprp_ctx { 220 + struct emmaprp_dev *dev; 221 + /* Abort requested by m2m */ 222 + int aborting; 223 + struct emmaprp_q_data q_data[2]; 224 + struct v4l2_m2m_ctx *m2m_ctx; 225 + }; 226 + 227 + static struct emmaprp_q_data *get_q_data(struct emmaprp_ctx *ctx, 228 + enum v4l2_buf_type type) 229 + { 230 + switch (type) { 231 + case V4L2_BUF_TYPE_VIDEO_OUTPUT: 232 + return &(ctx->q_data[V4L2_M2M_SRC]); 233 + case V4L2_BUF_TYPE_VIDEO_CAPTURE: 234 + return &(ctx->q_data[V4L2_M2M_DST]); 235 + default: 236 + BUG(); 237 + } 238 + return NULL; 239 + } 240 + 241 + /* 242 + * mem2mem callbacks 243 + */ 244 + static void emmaprp_job_abort(void *priv) 245 + { 246 + struct emmaprp_ctx *ctx = priv; 247 + struct emmaprp_dev *pcdev = ctx->dev; 248 + 249 + ctx->aborting = 1; 250 + 251 + dprintk(pcdev, "Aborting task\n"); 252 + 253 + v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx); 254 + } 255 + 256 + static void emmaprp_lock(void *priv) 257 + { 258 + struct emmaprp_ctx *ctx = priv; 259 + struct emmaprp_dev *pcdev = ctx->dev; 260 + mutex_lock(&pcdev->dev_mutex); 261 + } 262 + 263 + static void emmaprp_unlock(void *priv) 264 + { 265 + struct emmaprp_ctx *ctx = priv; 266 + struct emmaprp_dev *pcdev = ctx->dev; 267 + mutex_unlock(&pcdev->dev_mutex); 268 + } 269 + 270 + static inline void emmaprp_dump_regs(struct emmaprp_dev *pcdev) 271 + { 272 + dprintk(pcdev, 273 + "eMMa-PrP Registers:\n" 274 + " SOURCE_Y_PTR = 0x%08X\n" 275 + " SRC_FRAME_SIZE = 0x%08X\n" 276 + " DEST_Y_PTR = 0x%08X\n" 277 + " DEST_CR_PTR = 0x%08X\n" 278 + " DEST_CB_PTR = 0x%08X\n" 279 + " CH2_OUT_IMAGE_SIZE = 0x%08X\n" 280 + " CNTL = 0x%08X\n", 281 + readl(pcdev->base_emma + PRP_SOURCE_Y_PTR), 282 + readl(pcdev->base_emma + PRP_SRC_FRAME_SIZE), 283 + readl(pcdev->base_emma + PRP_DEST_Y_PTR), 284 + readl(pcdev->base_emma + PRP_DEST_CR_PTR), 285 + readl(pcdev->base_emma + PRP_DEST_CB_PTR), 286 + readl(pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE), 287 + readl(pcdev->base_emma + PRP_CNTL)); 288 + } 289 + 290 + static void emmaprp_device_run(void *priv) 291 + { 292 + struct emmaprp_ctx *ctx = priv; 293 + struct emmaprp_q_data *s_q_data, *d_q_data; 294 + struct vb2_buffer *src_buf, *dst_buf; 295 + struct emmaprp_dev *pcdev = ctx->dev; 296 + unsigned int s_width, s_height; 297 + unsigned int d_width, d_height; 298 + unsigned int d_size; 299 + dma_addr_t p_in, p_out; 300 + u32 tmp; 301 + 302 + src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 303 + dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 304 + 305 + s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 306 + s_width = s_q_data->width; 307 + s_height = s_q_data->height; 308 + 309 + d_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 310 + d_width = d_q_data->width; 311 + d_height = d_q_data->height; 312 + d_size = d_width * d_height; 313 + 314 + p_in = vb2_dma_contig_plane_dma_addr(src_buf, 0); 315 + p_out = vb2_dma_contig_plane_dma_addr(dst_buf, 0); 316 + if (!p_in || !p_out) { 317 + v4l2_err(&pcdev->v4l2_dev, 318 + "Acquiring kernel pointers to buffers failed\n"); 319 + return; 320 + } 321 + 322 + /* Input frame parameters */ 323 + writel(p_in, pcdev->base_emma + PRP_SOURCE_Y_PTR); 324 + writel(PRP_SIZE_WIDTH(s_width) | PRP_SIZE_HEIGHT(s_height), 325 + pcdev->base_emma + PRP_SRC_FRAME_SIZE); 326 + 327 + /* Output frame parameters */ 328 + writel(p_out, pcdev->base_emma + PRP_DEST_Y_PTR); 329 + writel(p_out + d_size, pcdev->base_emma + PRP_DEST_CB_PTR); 330 + writel(p_out + d_size + (d_size >> 2), 331 + pcdev->base_emma + PRP_DEST_CR_PTR); 332 + writel(PRP_SIZE_WIDTH(d_width) | PRP_SIZE_HEIGHT(d_height), 333 + pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE); 334 + 335 + /* IRQ configuration */ 336 + tmp = readl(pcdev->base_emma + PRP_INTR_CNTL); 337 + writel(tmp | PRP_INTR_RDERR | 338 + PRP_INTR_CH2WERR | 339 + PRP_INTR_CH2FC, 340 + pcdev->base_emma + PRP_INTR_CNTL); 341 + 342 + emmaprp_dump_regs(pcdev); 343 + 344 + /* Enable transfer */ 345 + tmp = readl(pcdev->base_emma + PRP_CNTL); 346 + writel(tmp | PRP_CNTL_CH2_OUT_YUV420 | 347 + PRP_CNTL_DATA_IN_YUV422 | 348 + PRP_CNTL_CH2EN, 349 + pcdev->base_emma + PRP_CNTL); 350 + } 351 + 352 + static irqreturn_t emmaprp_irq(int irq_emma, void *data) 353 + { 354 + struct emmaprp_dev *pcdev = data; 355 + struct emmaprp_ctx *curr_ctx; 356 + struct vb2_buffer *src_vb, *dst_vb; 357 + unsigned long flags; 358 + u32 irqst; 359 + 360 + /* Check irq flags and clear irq */ 361 + irqst = readl(pcdev->base_emma + PRP_INTRSTATUS); 362 + writel(irqst, pcdev->base_emma + PRP_INTRSTATUS); 363 + dprintk(pcdev, "irqst = 0x%08x\n", irqst); 364 + 365 + curr_ctx = v4l2_m2m_get_curr_priv(pcdev->m2m_dev); 366 + if (curr_ctx == NULL) { 367 + pr_err("Instance released before the end of transaction\n"); 368 + return IRQ_HANDLED; 369 + } 370 + 371 + if (!curr_ctx->aborting) { 372 + if ((irqst & PRP_INTR_ST_RDERR) || 373 + (irqst & PRP_INTR_ST_CH2WERR)) { 374 + pr_err("PrP bus error ocurred, this transfer is probably corrupted\n"); 375 + writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL); 376 + } else if (irqst & PRP_INTR_ST_CH2B1CI) { /* buffer ready */ 377 + src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx); 378 + dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx); 379 + 380 + spin_lock_irqsave(&pcdev->irqlock, flags); 381 + v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE); 382 + v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE); 383 + spin_unlock_irqrestore(&pcdev->irqlock, flags); 384 + } 385 + } 386 + 387 + v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx); 388 + return IRQ_HANDLED; 389 + } 390 + 391 + /* 392 + * video ioctls 393 + */ 394 + static int vidioc_querycap(struct file *file, void *priv, 395 + struct v4l2_capability *cap) 396 + { 397 + strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); 398 + strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); 399 + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT 400 + | V4L2_CAP_STREAMING; 401 + 402 + return 0; 403 + } 404 + 405 + static int enum_fmt(struct v4l2_fmtdesc *f, u32 type) 406 + { 407 + int i, num; 408 + struct emmaprp_fmt *fmt; 409 + 410 + num = 0; 411 + 412 + for (i = 0; i < NUM_FORMATS; ++i) { 413 + if (formats[i].types & type) { 414 + /* index-th format of type type found ? */ 415 + if (num == f->index) 416 + break; 417 + /* Correct type but haven't reached our index yet, 418 + * just increment per-type index */ 419 + ++num; 420 + } 421 + } 422 + 423 + if (i < NUM_FORMATS) { 424 + /* Format found */ 425 + fmt = &formats[i]; 426 + strlcpy(f->description, fmt->name, sizeof(f->description) - 1); 427 + f->pixelformat = fmt->fourcc; 428 + return 0; 429 + } 430 + 431 + /* Format not found */ 432 + return -EINVAL; 433 + } 434 + 435 + static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 436 + struct v4l2_fmtdesc *f) 437 + { 438 + return enum_fmt(f, MEM2MEM_CAPTURE); 439 + } 440 + 441 + static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, 442 + struct v4l2_fmtdesc *f) 443 + { 444 + return enum_fmt(f, MEM2MEM_OUTPUT); 445 + } 446 + 447 + static int vidioc_g_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f) 448 + { 449 + struct vb2_queue *vq; 450 + struct emmaprp_q_data *q_data; 451 + 452 + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 453 + if (!vq) 454 + return -EINVAL; 455 + 456 + q_data = get_q_data(ctx, f->type); 457 + 458 + f->fmt.pix.width = q_data->width; 459 + f->fmt.pix.height = q_data->height; 460 + f->fmt.pix.field = V4L2_FIELD_NONE; 461 + f->fmt.pix.pixelformat = q_data->fmt->fourcc; 462 + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) 463 + f->fmt.pix.bytesperline = q_data->width * 3 / 2; 464 + else /* YUYV */ 465 + f->fmt.pix.bytesperline = q_data->width * 2; 466 + f->fmt.pix.sizeimage = q_data->sizeimage; 467 + 468 + return 0; 469 + } 470 + 471 + static int vidioc_g_fmt_vid_out(struct file *file, void *priv, 472 + struct v4l2_format *f) 473 + { 474 + return vidioc_g_fmt(priv, f); 475 + } 476 + 477 + static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 478 + struct v4l2_format *f) 479 + { 480 + return vidioc_g_fmt(priv, f); 481 + } 482 + 483 + static int vidioc_try_fmt(struct v4l2_format *f) 484 + { 485 + enum v4l2_field field; 486 + 487 + 488 + if (!find_format(f)) 489 + return -EINVAL; 490 + 491 + field = f->fmt.pix.field; 492 + if (field == V4L2_FIELD_ANY) 493 + field = V4L2_FIELD_NONE; 494 + else if (V4L2_FIELD_NONE != field) 495 + return -EINVAL; 496 + 497 + /* V4L2 specification suggests the driver corrects the format struct 498 + * if any of the dimensions is unsupported */ 499 + f->fmt.pix.field = field; 500 + 501 + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) { 502 + v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W, 503 + W_ALIGN_YUV420, &f->fmt.pix.height, 504 + MIN_H, MAX_H, H_ALIGN, S_ALIGN); 505 + f->fmt.pix.bytesperline = f->fmt.pix.width * 3 / 2; 506 + } else { 507 + v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W, 508 + W_ALIGN_OTHERS, &f->fmt.pix.height, 509 + MIN_H, MAX_H, H_ALIGN, S_ALIGN); 510 + f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 511 + } 512 + f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 513 + 514 + return 0; 515 + } 516 + 517 + static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 518 + struct v4l2_format *f) 519 + { 520 + struct emmaprp_fmt *fmt; 521 + struct emmaprp_ctx *ctx = priv; 522 + 523 + fmt = find_format(f); 524 + if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) { 525 + v4l2_err(&ctx->dev->v4l2_dev, 526 + "Fourcc format (0x%08x) invalid.\n", 527 + f->fmt.pix.pixelformat); 528 + return -EINVAL; 529 + } 530 + 531 + return vidioc_try_fmt(f); 532 + } 533 + 534 + static int vidioc_try_fmt_vid_out(struct file *file, void *priv, 535 + struct v4l2_format *f) 536 + { 537 + struct emmaprp_fmt *fmt; 538 + struct emmaprp_ctx *ctx = priv; 539 + 540 + fmt = find_format(f); 541 + if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) { 542 + v4l2_err(&ctx->dev->v4l2_dev, 543 + "Fourcc format (0x%08x) invalid.\n", 544 + f->fmt.pix.pixelformat); 545 + return -EINVAL; 546 + } 547 + 548 + return vidioc_try_fmt(f); 549 + } 550 + 551 + static int vidioc_s_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f) 552 + { 553 + struct emmaprp_q_data *q_data; 554 + struct vb2_queue *vq; 555 + int ret; 556 + 557 + vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 558 + if (!vq) 559 + return -EINVAL; 560 + 561 + q_data = get_q_data(ctx, f->type); 562 + if (!q_data) 563 + return -EINVAL; 564 + 565 + if (vb2_is_busy(vq)) { 566 + v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); 567 + return -EBUSY; 568 + } 569 + 570 + ret = vidioc_try_fmt(f); 571 + if (ret) 572 + return ret; 573 + 574 + q_data->fmt = find_format(f); 575 + q_data->width = f->fmt.pix.width; 576 + q_data->height = f->fmt.pix.height; 577 + if (q_data->fmt->fourcc == V4L2_PIX_FMT_YUV420) 578 + q_data->sizeimage = q_data->width * q_data->height * 3 / 2; 579 + else /* YUYV */ 580 + q_data->sizeimage = q_data->width * q_data->height * 2; 581 + 582 + dprintk(ctx->dev, 583 + "Setting format for type %d, wxh: %dx%d, fmt: %d\n", 584 + f->type, q_data->width, q_data->height, q_data->fmt->fourcc); 585 + 586 + return 0; 587 + } 588 + 589 + static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 590 + struct v4l2_format *f) 591 + { 592 + int ret; 593 + 594 + ret = vidioc_try_fmt_vid_cap(file, priv, f); 595 + if (ret) 596 + return ret; 597 + 598 + return vidioc_s_fmt(priv, f); 599 + } 600 + 601 + static int vidioc_s_fmt_vid_out(struct file *file, void *priv, 602 + struct v4l2_format *f) 603 + { 604 + int ret; 605 + 606 + ret = vidioc_try_fmt_vid_out(file, priv, f); 607 + if (ret) 608 + return ret; 609 + 610 + return vidioc_s_fmt(priv, f); 611 + } 612 + 613 + static int vidioc_reqbufs(struct file *file, void *priv, 614 + struct v4l2_requestbuffers *reqbufs) 615 + { 616 + struct emmaprp_ctx *ctx = priv; 617 + 618 + return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); 619 + } 620 + 621 + static int vidioc_querybuf(struct file *file, void *priv, 622 + struct v4l2_buffer *buf) 623 + { 624 + struct emmaprp_ctx *ctx = priv; 625 + 626 + return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); 627 + } 628 + 629 + static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) 630 + { 631 + struct emmaprp_ctx *ctx = priv; 632 + 633 + return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); 634 + } 635 + 636 + static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) 637 + { 638 + struct emmaprp_ctx *ctx = priv; 639 + 640 + return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); 641 + } 642 + 643 + static int vidioc_streamon(struct file *file, void *priv, 644 + enum v4l2_buf_type type) 645 + { 646 + struct emmaprp_ctx *ctx = priv; 647 + 648 + return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); 649 + } 650 + 651 + static int vidioc_streamoff(struct file *file, void *priv, 652 + enum v4l2_buf_type type) 653 + { 654 + struct emmaprp_ctx *ctx = priv; 655 + 656 + return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); 657 + } 658 + 659 + static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = { 660 + .vidioc_querycap = vidioc_querycap, 661 + 662 + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 663 + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 664 + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 665 + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 666 + 667 + .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, 668 + .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out, 669 + .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, 670 + .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, 671 + 672 + .vidioc_reqbufs = vidioc_reqbufs, 673 + .vidioc_querybuf = vidioc_querybuf, 674 + 675 + .vidioc_qbuf = vidioc_qbuf, 676 + .vidioc_dqbuf = vidioc_dqbuf, 677 + 678 + .vidioc_streamon = vidioc_streamon, 679 + .vidioc_streamoff = vidioc_streamoff, 680 + }; 681 + 682 + 683 + /* 684 + * Queue operations 685 + */ 686 + static int emmaprp_queue_setup(struct vb2_queue *vq, 687 + const struct v4l2_format *fmt, 688 + unsigned int *nbuffers, unsigned int *nplanes, 689 + unsigned int sizes[], void *alloc_ctxs[]) 690 + { 691 + struct emmaprp_ctx *ctx = vb2_get_drv_priv(vq); 692 + struct emmaprp_q_data *q_data; 693 + unsigned int size, count = *nbuffers; 694 + 695 + q_data = get_q_data(ctx, vq->type); 696 + 697 + if (q_data->fmt->fourcc == V4L2_PIX_FMT_YUV420) 698 + size = q_data->width * q_data->height * 3 / 2; 699 + else 700 + size = q_data->width * q_data->height * 2; 701 + 702 + while (size * count > MEM2MEM_VID_MEM_LIMIT) 703 + (count)--; 704 + 705 + *nplanes = 1; 706 + *nbuffers = count; 707 + sizes[0] = size; 708 + 709 + alloc_ctxs[0] = ctx->dev->alloc_ctx; 710 + 711 + dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size); 712 + 713 + return 0; 714 + } 715 + 716 + static int emmaprp_buf_prepare(struct vb2_buffer *vb) 717 + { 718 + struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 719 + struct emmaprp_q_data *q_data; 720 + 721 + dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type); 722 + 723 + q_data = get_q_data(ctx, vb->vb2_queue->type); 724 + 725 + if (vb2_plane_size(vb, 0) < q_data->sizeimage) { 726 + dprintk(ctx->dev, "%s data will not fit into plane" 727 + "(%lu < %lu)\n", __func__, 728 + vb2_plane_size(vb, 0), 729 + (long)q_data->sizeimage); 730 + return -EINVAL; 731 + } 732 + 733 + vb2_set_plane_payload(vb, 0, q_data->sizeimage); 734 + 735 + return 0; 736 + } 737 + 738 + static void emmaprp_buf_queue(struct vb2_buffer *vb) 739 + { 740 + struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 741 + v4l2_m2m_buf_queue(ctx->m2m_ctx, vb); 742 + } 743 + 744 + static struct vb2_ops emmaprp_qops = { 745 + .queue_setup = emmaprp_queue_setup, 746 + .buf_prepare = emmaprp_buf_prepare, 747 + .buf_queue = emmaprp_buf_queue, 748 + }; 749 + 750 + static int queue_init(void *priv, struct vb2_queue *src_vq, 751 + struct vb2_queue *dst_vq) 752 + { 753 + struct emmaprp_ctx *ctx = priv; 754 + int ret; 755 + 756 + memset(src_vq, 0, sizeof(*src_vq)); 757 + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 758 + src_vq->io_modes = VB2_MMAP; 759 + src_vq->drv_priv = ctx; 760 + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 761 + src_vq->ops = &emmaprp_qops; 762 + src_vq->mem_ops = &vb2_dma_contig_memops; 763 + 764 + ret = vb2_queue_init(src_vq); 765 + if (ret) 766 + return ret; 767 + 768 + memset(dst_vq, 0, sizeof(*dst_vq)); 769 + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 770 + dst_vq->io_modes = VB2_MMAP; 771 + dst_vq->drv_priv = ctx; 772 + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 773 + dst_vq->ops = &emmaprp_qops; 774 + dst_vq->mem_ops = &vb2_dma_contig_memops; 775 + 776 + return vb2_queue_init(dst_vq); 777 + } 778 + 779 + /* 780 + * File operations 781 + */ 782 + static int emmaprp_open(struct file *file) 783 + { 784 + struct emmaprp_dev *pcdev = video_drvdata(file); 785 + struct emmaprp_ctx *ctx; 786 + 787 + ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 788 + if (!ctx) 789 + return -ENOMEM; 790 + 791 + file->private_data = ctx; 792 + ctx->dev = pcdev; 793 + 794 + ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init); 795 + 796 + if (IS_ERR(ctx->m2m_ctx)) { 797 + int ret = PTR_ERR(ctx->m2m_ctx); 798 + 799 + kfree(ctx); 800 + return ret; 801 + } 802 + 803 + clk_enable(pcdev->clk_emma); 804 + ctx->q_data[V4L2_M2M_SRC].fmt = &formats[1]; 805 + ctx->q_data[V4L2_M2M_DST].fmt = &formats[0]; 806 + 807 + dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx); 808 + 809 + return 0; 810 + } 811 + 812 + static int emmaprp_release(struct file *file) 813 + { 814 + struct emmaprp_dev *pcdev = video_drvdata(file); 815 + struct emmaprp_ctx *ctx = file->private_data; 816 + 817 + dprintk(pcdev, "Releasing instance %p\n", ctx); 818 + 819 + clk_disable(pcdev->clk_emma); 820 + v4l2_m2m_ctx_release(ctx->m2m_ctx); 821 + kfree(ctx); 822 + 823 + return 0; 824 + } 825 + 826 + static unsigned int emmaprp_poll(struct file *file, 827 + struct poll_table_struct *wait) 828 + { 829 + struct emmaprp_ctx *ctx = file->private_data; 830 + 831 + return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); 832 + } 833 + 834 + static int emmaprp_mmap(struct file *file, struct vm_area_struct *vma) 835 + { 836 + struct emmaprp_ctx *ctx = file->private_data; 837 + 838 + return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); 839 + } 840 + 841 + static const struct v4l2_file_operations emmaprp_fops = { 842 + .owner = THIS_MODULE, 843 + .open = emmaprp_open, 844 + .release = emmaprp_release, 845 + .poll = emmaprp_poll, 846 + .unlocked_ioctl = video_ioctl2, 847 + .mmap = emmaprp_mmap, 848 + }; 849 + 850 + static struct video_device emmaprp_videodev = { 851 + .name = MEM2MEM_NAME, 852 + .fops = &emmaprp_fops, 853 + .ioctl_ops = &emmaprp_ioctl_ops, 854 + .minor = -1, 855 + .release = video_device_release, 856 + }; 857 + 858 + static struct v4l2_m2m_ops m2m_ops = { 859 + .device_run = emmaprp_device_run, 860 + .job_abort = emmaprp_job_abort, 861 + .lock = emmaprp_lock, 862 + .unlock = emmaprp_unlock, 863 + }; 864 + 865 + static int emmaprp_probe(struct platform_device *pdev) 866 + { 867 + struct emmaprp_dev *pcdev; 868 + struct video_device *vfd; 869 + struct resource *res_emma; 870 + int irq_emma; 871 + int ret; 872 + 873 + pcdev = kzalloc(sizeof *pcdev, GFP_KERNEL); 874 + if (!pcdev) 875 + return -ENOMEM; 876 + 877 + spin_lock_init(&pcdev->irqlock); 878 + 879 + pcdev->clk_emma = clk_get(&pdev->dev, NULL); 880 + if (IS_ERR(pcdev->clk_emma)) { 881 + ret = PTR_ERR(pcdev->clk_emma); 882 + goto free_dev; 883 + } 884 + 885 + irq_emma = platform_get_irq(pdev, 0); 886 + res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 0); 887 + if (irq_emma < 0 || res_emma == NULL) { 888 + dev_err(&pdev->dev, "Missing platform resources data\n"); 889 + ret = -ENODEV; 890 + goto free_clk; 891 + } 892 + 893 + ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev); 894 + if (ret) 895 + goto free_clk; 896 + 897 + mutex_init(&pcdev->dev_mutex); 898 + 899 + vfd = video_device_alloc(); 900 + if (!vfd) { 901 + v4l2_err(&pcdev->v4l2_dev, "Failed to allocate video device\n"); 902 + ret = -ENOMEM; 903 + goto unreg_dev; 904 + } 905 + 906 + *vfd = emmaprp_videodev; 907 + vfd->lock = &pcdev->dev_mutex; 908 + 909 + video_set_drvdata(vfd, pcdev); 910 + snprintf(vfd->name, sizeof(vfd->name), "%s", emmaprp_videodev.name); 911 + pcdev->vfd = vfd; 912 + v4l2_info(&pcdev->v4l2_dev, EMMAPRP_MODULE_NAME 913 + " Device registered as /dev/video%d\n", vfd->num); 914 + 915 + platform_set_drvdata(pdev, pcdev); 916 + 917 + if (devm_request_mem_region(&pdev->dev, res_emma->start, 918 + resource_size(res_emma), MEM2MEM_NAME) == NULL) 919 + goto rel_vdev; 920 + 921 + pcdev->base_emma = devm_ioremap(&pdev->dev, res_emma->start, 922 + resource_size(res_emma)); 923 + if (!pcdev->base_emma) 924 + goto rel_vdev; 925 + 926 + pcdev->irq_emma = irq_emma; 927 + pcdev->res_emma = res_emma; 928 + 929 + if (devm_request_irq(&pdev->dev, pcdev->irq_emma, emmaprp_irq, 930 + 0, MEM2MEM_NAME, pcdev) < 0) 931 + goto rel_vdev; 932 + 933 + pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 934 + if (IS_ERR(pcdev->alloc_ctx)) { 935 + v4l2_err(&pcdev->v4l2_dev, "Failed to alloc vb2 context\n"); 936 + ret = PTR_ERR(pcdev->alloc_ctx); 937 + goto rel_vdev; 938 + } 939 + 940 + pcdev->m2m_dev = v4l2_m2m_init(&m2m_ops); 941 + if (IS_ERR(pcdev->m2m_dev)) { 942 + v4l2_err(&pcdev->v4l2_dev, "Failed to init mem2mem device\n"); 943 + ret = PTR_ERR(pcdev->m2m_dev); 944 + goto rel_ctx; 945 + } 946 + 947 + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); 948 + if (ret) { 949 + v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n"); 950 + goto rel_m2m; 951 + } 952 + 953 + return 0; 954 + 955 + 956 + rel_m2m: 957 + v4l2_m2m_release(pcdev->m2m_dev); 958 + rel_ctx: 959 + vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 960 + rel_vdev: 961 + video_device_release(vfd); 962 + unreg_dev: 963 + v4l2_device_unregister(&pcdev->v4l2_dev); 964 + free_clk: 965 + clk_put(pcdev->clk_emma); 966 + free_dev: 967 + kfree(pcdev); 968 + 969 + return ret; 970 + } 971 + 972 + static int emmaprp_remove(struct platform_device *pdev) 973 + { 974 + struct emmaprp_dev *pcdev = platform_get_drvdata(pdev); 975 + 976 + v4l2_info(&pcdev->v4l2_dev, "Removing " EMMAPRP_MODULE_NAME); 977 + 978 + video_unregister_device(pcdev->vfd); 979 + v4l2_m2m_release(pcdev->m2m_dev); 980 + vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 981 + v4l2_device_unregister(&pcdev->v4l2_dev); 982 + clk_put(pcdev->clk_emma); 983 + kfree(pcdev); 984 + 985 + return 0; 986 + } 987 + 988 + static struct platform_driver emmaprp_pdrv = { 989 + .probe = emmaprp_probe, 990 + .remove = emmaprp_remove, 991 + .driver = { 992 + .name = MEM2MEM_NAME, 993 + .owner = THIS_MODULE, 994 + }, 995 + }; 996 + 997 + static void __exit emmaprp_exit(void) 998 + { 999 + platform_driver_unregister(&emmaprp_pdrv); 1000 + } 1001 + 1002 + static int __init emmaprp_init(void) 1003 + { 1004 + return platform_driver_register(&emmaprp_pdrv); 1005 + } 1006 + 1007 + module_init(emmaprp_init); 1008 + module_exit(emmaprp_exit);
+2 -13
drivers/media/video/noon010pc30.c
··· 725 725 726 726 mutex_init(&info->lock); 727 727 sd = &info->sd; 728 - strlcpy(sd->name, MODULE_NAME, sizeof(sd->name)); 729 728 v4l2_i2c_subdev_init(sd, client, &noon010_ops); 729 + strlcpy(sd->name, MODULE_NAME, sizeof(sd->name)); 730 730 731 731 sd->internal_ops = &noon010_subdev_internal_ops; 732 732 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ··· 844 844 .id_table = noon010_id, 845 845 }; 846 846 847 - static int __init noon010_init(void) 848 - { 849 - return i2c_add_driver(&noon010_i2c_driver); 850 - } 851 - 852 - static void __exit noon010_exit(void) 853 - { 854 - i2c_del_driver(&noon010_i2c_driver); 855 - } 856 - 857 - module_init(noon010_init); 858 - module_exit(noon010_exit); 847 + module_i2c_driver(noon010_i2c_driver); 859 848 860 849 MODULE_DESCRIPTION("Siliconfile NOON010PC30 camera driver"); 861 850 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+1 -2
drivers/media/video/omap/omap_vout.c
··· 2268 2268 .driver = { 2269 2269 .name = VOUT_NAME, 2270 2270 }, 2271 - .probe = omap_vout_probe, 2272 2271 .remove = omap_vout_remove, 2273 2272 }; 2274 2273 2275 2274 static int __init omap_vout_init(void) 2276 2275 { 2277 - if (platform_driver_register(&omap_vout_driver) != 0) { 2276 + if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) { 2278 2277 printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n"); 2279 2278 return -EINVAL; 2280 2279 }
+1 -15
drivers/media/video/ov2640.c
··· 1103 1103 .id_table = ov2640_id, 1104 1104 }; 1105 1105 1106 - /* 1107 - * Module functions 1108 - */ 1109 - static int __init ov2640_module_init(void) 1110 - { 1111 - return i2c_add_driver(&ov2640_i2c_driver); 1112 - } 1113 - 1114 - static void __exit ov2640_module_exit(void) 1115 - { 1116 - i2c_del_driver(&ov2640_i2c_driver); 1117 - } 1118 - 1119 - module_init(ov2640_module_init); 1120 - module_exit(ov2640_module_exit); 1106 + module_i2c_driver(ov2640_i2c_driver); 1121 1107 1122 1108 MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor"); 1123 1109 MODULE_AUTHOR("Alberto Panizzo");
+1 -12
drivers/media/video/ov5642.c
··· 1068 1068 .id_table = ov5642_id, 1069 1069 }; 1070 1070 1071 - static int __init ov5642_mod_init(void) 1072 - { 1073 - return i2c_add_driver(&ov5642_i2c_driver); 1074 - } 1075 - 1076 - static void __exit ov5642_mod_exit(void) 1077 - { 1078 - i2c_del_driver(&ov5642_i2c_driver); 1079 - } 1080 - 1081 - module_init(ov5642_mod_init); 1082 - module_exit(ov5642_mod_exit); 1071 + module_i2c_driver(ov5642_i2c_driver); 1083 1072 1084 1073 MODULE_DESCRIPTION("Omnivision OV5642 Camera driver"); 1085 1074 MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
+1 -12
drivers/media/video/ov6650.c
··· 1046 1046 .id_table = ov6650_id, 1047 1047 }; 1048 1048 1049 - static int __init ov6650_module_init(void) 1050 - { 1051 - return i2c_add_driver(&ov6650_i2c_driver); 1052 - } 1053 - 1054 - static void __exit ov6650_module_exit(void) 1055 - { 1056 - i2c_del_driver(&ov6650_i2c_driver); 1057 - } 1058 - 1059 - module_init(ov6650_module_init); 1060 - module_exit(ov6650_module_exit); 1049 + module_i2c_driver(ov6650_i2c_driver); 1061 1050 1062 1051 MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV6650"); 1063 1052 MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
+1 -12
drivers/media/video/ov7670.c
··· 1583 1583 .id_table = ov7670_id, 1584 1584 }; 1585 1585 1586 - static __init int init_ov7670(void) 1587 - { 1588 - return i2c_add_driver(&ov7670_driver); 1589 - } 1590 - 1591 - static __exit void exit_ov7670(void) 1592 - { 1593 - i2c_del_driver(&ov7670_driver); 1594 - } 1595 - 1596 - module_init(init_ov7670); 1597 - module_exit(exit_ov7670); 1586 + module_i2c_driver(ov7670_driver);
+1 -16
drivers/media/video/ov772x.c
··· 1123 1123 .id_table = ov772x_id, 1124 1124 }; 1125 1125 1126 - /* 1127 - * module function 1128 - */ 1129 - 1130 - static int __init ov772x_module_init(void) 1131 - { 1132 - return i2c_add_driver(&ov772x_i2c_driver); 1133 - } 1134 - 1135 - static void __exit ov772x_module_exit(void) 1136 - { 1137 - i2c_del_driver(&ov772x_i2c_driver); 1138 - } 1139 - 1140 - module_init(ov772x_module_init); 1141 - module_exit(ov772x_module_exit); 1126 + module_i2c_driver(ov772x_i2c_driver); 1142 1127 1143 1128 MODULE_DESCRIPTION("SoC Camera driver for ov772x"); 1144 1129 MODULE_AUTHOR("Kuninori Morimoto");
+1 -12
drivers/media/video/ov9640.c
··· 738 738 .id_table = ov9640_id, 739 739 }; 740 740 741 - static int __init ov9640_module_init(void) 742 - { 743 - return i2c_add_driver(&ov9640_i2c_driver); 744 - } 745 - 746 - static void __exit ov9640_module_exit(void) 747 - { 748 - i2c_del_driver(&ov9640_i2c_driver); 749 - } 750 - 751 - module_init(ov9640_module_init); 752 - module_exit(ov9640_module_exit); 741 + module_i2c_driver(ov9640_i2c_driver); 753 742 754 743 MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx"); 755 744 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+1 -12
drivers/media/video/ov9740.c
··· 998 998 .id_table = ov9740_id, 999 999 }; 1000 1000 1001 - static int __init ov9740_module_init(void) 1002 - { 1003 - return i2c_add_driver(&ov9740_i2c_driver); 1004 - } 1005 - 1006 - static void __exit ov9740_module_exit(void) 1007 - { 1008 - i2c_del_driver(&ov9740_i2c_driver); 1009 - } 1010 - 1011 - module_init(ov9740_module_init); 1012 - module_exit(ov9740_module_exit); 1001 + module_i2c_driver(ov9740_i2c_driver); 1013 1002 1014 1003 MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740"); 1015 1004 MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>");
+10
drivers/media/video/pvrusb2/pvrusb2-devattr.c
··· 320 320 .probe_tuner = TDA829X_DONT_PROBE, 321 321 }; 322 322 323 + static struct tda18271_std_map hauppauge_tda18271_dvbt_std_map = { 324 + .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, 325 + .if_lvl = 1, .rfagc_top = 0x37, }, 326 + .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5, 327 + .if_lvl = 1, .rfagc_top = 0x37, }, 328 + .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6, 329 + .if_lvl = 1, .rfagc_top = 0x37, }, 330 + }; 331 + 323 332 static struct tda18271_config hauppauge_tda18271_dvb_config = { 333 + .std_map = &hauppauge_tda18271_dvbt_std_map, 324 334 .gate = TDA18271_GATE_ANALOG, 325 335 .output_opt = TDA18271_OUTPUT_LT_OFF, 326 336 };
-1
drivers/media/video/pvrusb2/pvrusb2-v4l2.c
··· 96 96 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | 97 97 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | 98 98 V4L2_CAP_READWRITE), 99 - .reserved = {0,0,0,0} 100 99 }; 101 100 102 101 static struct v4l2_fmtdesc pvr_fmtdesc [] = {
+1 -9
drivers/media/video/pwc/pwc-v4l.c
··· 1146 1146 return ret; 1147 1147 } 1148 1148 1149 - static int pwc_log_status(struct file *file, void *priv) 1150 - { 1151 - struct pwc_device *pdev = video_drvdata(file); 1152 - 1153 - v4l2_ctrl_handler_log_status(&pdev->ctrl_handler, PWC_NAME); 1154 - return 0; 1155 - } 1156 - 1157 1149 const struct v4l2_ioctl_ops pwc_ioctl_ops = { 1158 1150 .vidioc_querycap = pwc_querycap, 1159 1151 .vidioc_enum_input = pwc_enum_input, ··· 1161 1169 .vidioc_dqbuf = pwc_dqbuf, 1162 1170 .vidioc_streamon = pwc_streamon, 1163 1171 .vidioc_streamoff = pwc_streamoff, 1164 - .vidioc_log_status = pwc_log_status, 1172 + .vidioc_log_status = v4l2_ctrl_log_status, 1165 1173 .vidioc_enum_framesizes = pwc_enum_framesizes, 1166 1174 .vidioc_enum_frameintervals = pwc_enum_frameintervals, 1167 1175 .vidioc_g_parm = pwc_g_parm,
+2 -2
drivers/media/video/pxa_camera.c
··· 921 921 /* "Safe default" - 13MHz */ 922 922 recalculate_fifo_timeout(pcdev, 13000000); 923 923 924 - clk_enable(pcdev->clk); 924 + clk_prepare_enable(pcdev->clk); 925 925 } 926 926 927 927 static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) 928 928 { 929 - clk_disable(pcdev->clk); 929 + clk_disable_unprepare(pcdev->clk); 930 930 } 931 931 932 932 static irqreturn_t pxa_camera_irq(int irq, void *data)
+1 -12
drivers/media/video/rj54n1cb0c.c
··· 1407 1407 .id_table = rj54n1_id, 1408 1408 }; 1409 1409 1410 - static int __init rj54n1_mod_init(void) 1411 - { 1412 - return i2c_add_driver(&rj54n1_i2c_driver); 1413 - } 1414 - 1415 - static void __exit rj54n1_mod_exit(void) 1416 - { 1417 - i2c_del_driver(&rj54n1_i2c_driver); 1418 - } 1419 - 1420 - module_init(rj54n1_mod_init); 1421 - module_exit(rj54n1_mod_exit); 1410 + module_i2c_driver(rj54n1_i2c_driver); 1422 1411 1423 1412 MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver"); 1424 1413 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+16 -17
drivers/media/video/s2255drv.c
··· 134 134 135 135 /* usb config commands */ 136 136 #define IN_DATA_TOKEN cpu_to_le32(0x2255c0de) 137 - #define CMD_2255 cpu_to_le32(0xc2255000) 137 + #define CMD_2255 0xc2255000 138 138 #define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10)) 139 139 #define CMD_START cpu_to_le32((CMD_2255 | 0x20)) 140 140 #define CMD_STOP cpu_to_le32((CMD_2255 | 0x30)) ··· 852 852 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 853 853 struct v4l2_fmtdesc *f) 854 854 { 855 - int index = 0; 856 - if (f) 857 - index = f->index; 855 + int index = f->index; 858 856 859 857 if (index >= ARRAY_SIZE(formats)) 860 858 return -EINVAL; 861 - if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) || 862 - (formats[index].fourcc == V4L2_PIX_FMT_MJPEG))) 863 - return -EINVAL; 859 + if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) || 860 + (formats[index].fourcc == V4L2_PIX_FMT_MJPEG))) 861 + return -EINVAL; 864 862 dprintk(4, "name %s\n", formats[index].name); 865 863 strlcpy(f->description, formats[index].name, sizeof(f->description)); 866 864 f->pixelformat = formats[index].fourcc; ··· 2025 2027 pdata[1]); 2026 2028 offset = jj + PREFIX_SIZE; 2027 2029 bframe = 1; 2028 - cc = pdword[1]; 2030 + cc = le32_to_cpu(pdword[1]); 2029 2031 if (cc >= MAX_CHANNELS) { 2030 2032 printk(KERN_ERR 2031 2033 "bad channel\n"); ··· 2034 2036 /* reverse it */ 2035 2037 dev->cc = G_chnmap[cc]; 2036 2038 channel = &dev->channel[dev->cc]; 2037 - payload = pdword[3]; 2039 + payload = le32_to_cpu(pdword[3]); 2038 2040 if (payload > channel->req_image_size) { 2039 2041 channel->bad_payload++; 2040 2042 /* discard the bad frame */ 2041 2043 return -EINVAL; 2042 2044 } 2043 2045 channel->pkt_size = payload; 2044 - channel->jpg_size = pdword[4]; 2046 + channel->jpg_size = le32_to_cpu(pdword[4]); 2045 2047 break; 2046 2048 case S2255_MARKER_RESPONSE: 2047 2049 2048 2050 pdata += DEF_USB_BLOCK; 2049 2051 jj += DEF_USB_BLOCK; 2050 - if (pdword[1] >= MAX_CHANNELS) 2052 + if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS) 2051 2053 break; 2052 - cc = G_chnmap[pdword[1]]; 2054 + cc = G_chnmap[le32_to_cpu(pdword[1])]; 2053 2055 if (cc >= MAX_CHANNELS) 2054 2056 break; 2055 2057 channel = &dev->channel[cc]; ··· 2072 2074 wake_up(&dev->fw_data->wait_fw); 2073 2075 break; 2074 2076 case S2255_RESPONSE_STATUS: 2075 - channel->vidstatus = pdword[3]; 2077 + channel->vidstatus = le32_to_cpu(pdword[3]); 2076 2078 channel->vidstatus_ready = 1; 2077 2079 wake_up(&channel->wait_vidstatus); 2078 2080 dprintk(5, "got vidstatus %x chan %d\n", 2079 - pdword[3], cc); 2081 + le32_to_cpu(pdword[3]), cc); 2080 2082 break; 2081 2083 default: 2082 2084 printk(KERN_INFO "s2255 unknown resp\n"); ··· 2603 2605 __le32 *pRel; 2604 2606 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; 2605 2607 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); 2606 - dev->dsp_fw_ver = *pRel; 2607 - if (*pRel < S2255_CUR_DSP_FWVER) 2608 + dev->dsp_fw_ver = le32_to_cpu(*pRel); 2609 + if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER) 2608 2610 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n"); 2609 - if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER) 2611 + if (dev->pid == 0x2257 && 2612 + dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER) 2610 2613 printk(KERN_WARNING "s2255: 2257 requires firmware %d" 2611 2614 " or above.\n", S2255_MIN_DSP_COLORFILTER); 2612 2615 }
+2 -13
drivers/media/video/s5k6aa.c
··· 1582 1582 s5k6aa->inv_vflip = pdata->vert_flip; 1583 1583 1584 1584 sd = &s5k6aa->sd; 1585 - strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name)); 1586 1585 v4l2_i2c_subdev_init(sd, client, &s5k6aa_subdev_ops); 1586 + strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name)); 1587 1587 1588 1588 sd->internal_ops = &s5k6aa_subdev_internal_ops; 1589 1589 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ··· 1663 1663 .id_table = s5k6aa_id, 1664 1664 }; 1665 1665 1666 - static int __init s5k6aa_init(void) 1667 - { 1668 - return i2c_add_driver(&s5k6aa_i2c_driver); 1669 - } 1670 - 1671 - static void __exit s5k6aa_exit(void) 1672 - { 1673 - i2c_del_driver(&s5k6aa_i2c_driver); 1674 - } 1675 - 1676 - module_init(s5k6aa_init); 1677 - module_exit(s5k6aa_exit); 1666 + module_i2c_driver(s5k6aa_i2c_driver); 1678 1667 1679 1668 MODULE_DESCRIPTION("Samsung S5K6AA(FX) SXGA camera driver"); 1680 1669 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+97 -30
drivers/media/video/s5p-fimc/fimc-capture.c
··· 1019 1019 return vb2_dqbuf(&fimc->vid_cap.vbq, buf, file->f_flags & O_NONBLOCK); 1020 1020 } 1021 1021 1022 - static int fimc_cap_cropcap(struct file *file, void *fh, 1023 - struct v4l2_cropcap *cr) 1022 + static int fimc_cap_create_bufs(struct file *file, void *priv, 1023 + struct v4l2_create_buffers *create) 1024 1024 { 1025 1025 struct fimc_dev *fimc = video_drvdata(file); 1026 - struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; 1027 1026 1028 - if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1029 - return -EINVAL; 1030 - 1031 - cr->bounds.left = 0; 1032 - cr->bounds.top = 0; 1033 - cr->bounds.width = f->o_width; 1034 - cr->bounds.height = f->o_height; 1035 - cr->defrect = cr->bounds; 1036 - 1037 - return 0; 1027 + return vb2_create_bufs(&fimc->vid_cap.vbq, create); 1038 1028 } 1039 1029 1040 - static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1030 + static int fimc_cap_prepare_buf(struct file *file, void *priv, 1031 + struct v4l2_buffer *b) 1041 1032 { 1042 1033 struct fimc_dev *fimc = video_drvdata(file); 1043 - struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; 1044 1034 1045 - cr->c.left = f->offs_h; 1046 - cr->c.top = f->offs_v; 1047 - cr->c.width = f->width; 1048 - cr->c.height = f->height; 1049 - 1050 - return 0; 1035 + return vb2_prepare_buf(&fimc->vid_cap.vbq, b); 1051 1036 } 1052 1037 1053 - static int fimc_cap_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1038 + static int fimc_cap_g_selection(struct file *file, void *fh, 1039 + struct v4l2_selection *s) 1054 1040 { 1055 1041 struct fimc_dev *fimc = video_drvdata(file); 1056 1042 struct fimc_ctx *ctx = fimc->vid_cap.ctx; 1057 - struct fimc_frame *ff; 1043 + struct fimc_frame *f = &ctx->s_frame; 1044 + 1045 + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1046 + return -EINVAL; 1047 + 1048 + switch (s->target) { 1049 + case V4L2_SEL_TGT_COMPOSE_DEFAULT: 1050 + case V4L2_SEL_TGT_COMPOSE_BOUNDS: 1051 + f = &ctx->d_frame; 1052 + case V4L2_SEL_TGT_CROP_BOUNDS: 1053 + case V4L2_SEL_TGT_CROP_DEFAULT: 1054 + s->r.left = 0; 1055 + s->r.top = 0; 1056 + s->r.width = f->o_width; 1057 + s->r.height = f->o_height; 1058 + return 0; 1059 + 1060 + case V4L2_SEL_TGT_COMPOSE_ACTIVE: 1061 + f = &ctx->d_frame; 1062 + case V4L2_SEL_TGT_CROP_ACTIVE: 1063 + s->r.left = f->offs_h; 1064 + s->r.top = f->offs_v; 1065 + s->r.width = f->width; 1066 + s->r.height = f->height; 1067 + return 0; 1068 + } 1069 + 1070 + return -EINVAL; 1071 + } 1072 + 1073 + /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */ 1074 + int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b) 1075 + { 1076 + if (a->left < b->left || a->top < b->top) 1077 + return 0; 1078 + if (a->left + a->width > b->left + b->width) 1079 + return 0; 1080 + if (a->top + a->height > b->top + b->height) 1081 + return 0; 1082 + 1083 + return 1; 1084 + } 1085 + 1086 + static int fimc_cap_s_selection(struct file *file, void *fh, 1087 + struct v4l2_selection *s) 1088 + { 1089 + struct fimc_dev *fimc = video_drvdata(file); 1090 + struct fimc_ctx *ctx = fimc->vid_cap.ctx; 1091 + struct v4l2_rect rect = s->r; 1092 + struct fimc_frame *f; 1058 1093 unsigned long flags; 1094 + unsigned int pad; 1059 1095 1060 - fimc_capture_try_crop(ctx, &cr->c, FIMC_SD_PAD_SINK); 1061 - ff = &ctx->s_frame; 1096 + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1097 + return -EINVAL; 1062 1098 1099 + switch (s->target) { 1100 + case V4L2_SEL_TGT_COMPOSE_DEFAULT: 1101 + case V4L2_SEL_TGT_COMPOSE_BOUNDS: 1102 + case V4L2_SEL_TGT_COMPOSE_ACTIVE: 1103 + f = &ctx->d_frame; 1104 + pad = FIMC_SD_PAD_SOURCE; 1105 + break; 1106 + case V4L2_SEL_TGT_CROP_BOUNDS: 1107 + case V4L2_SEL_TGT_CROP_DEFAULT: 1108 + case V4L2_SEL_TGT_CROP_ACTIVE: 1109 + f = &ctx->s_frame; 1110 + pad = FIMC_SD_PAD_SINK; 1111 + break; 1112 + default: 1113 + return -EINVAL; 1114 + } 1115 + 1116 + fimc_capture_try_crop(ctx, &rect, pad); 1117 + 1118 + if (s->flags & V4L2_SEL_FLAG_LE && 1119 + !enclosed_rectangle(&rect, &s->r)) 1120 + return -ERANGE; 1121 + 1122 + if (s->flags & V4L2_SEL_FLAG_GE && 1123 + !enclosed_rectangle(&s->r, &rect)) 1124 + return -ERANGE; 1125 + 1126 + s->r = rect; 1063 1127 spin_lock_irqsave(&fimc->slock, flags); 1064 - set_frame_crop(ff, cr->c.left, cr->c.top, cr->c.width, cr->c.height); 1065 - set_bit(ST_CAPT_APPLY_CFG, &fimc->state); 1128 + set_frame_crop(f, s->r.left, s->r.top, s->r.width, 1129 + s->r.height); 1066 1130 spin_unlock_irqrestore(&fimc->slock, flags); 1067 1131 1132 + set_bit(ST_CAPT_APPLY_CFG, &fimc->state); 1068 1133 return 0; 1069 1134 } 1070 1135 ··· 1147 1082 .vidioc_qbuf = fimc_cap_qbuf, 1148 1083 .vidioc_dqbuf = fimc_cap_dqbuf, 1149 1084 1085 + .vidioc_prepare_buf = fimc_cap_prepare_buf, 1086 + .vidioc_create_bufs = fimc_cap_create_bufs, 1087 + 1150 1088 .vidioc_streamon = fimc_cap_streamon, 1151 1089 .vidioc_streamoff = fimc_cap_streamoff, 1152 1090 1153 - .vidioc_g_crop = fimc_cap_g_crop, 1154 - .vidioc_s_crop = fimc_cap_s_crop, 1155 - .vidioc_cropcap = fimc_cap_cropcap, 1091 + .vidioc_g_selection = fimc_cap_g_selection, 1092 + .vidioc_s_selection = fimc_cap_s_selection, 1156 1093 1157 1094 .vidioc_enum_input = fimc_cap_enum_input, 1158 1095 .vidioc_s_input = fimc_cap_s_input,
+32 -53
drivers/media/video/s5p-fimc/fimc-core.c
··· 1602 1602 { 1603 1603 int i; 1604 1604 for (i = 0; i < fimc->num_clocks; i++) { 1605 - if (fimc->clock[i]) 1606 - clk_put(fimc->clock[i]); 1605 + if (IS_ERR_OR_NULL(fimc->clock[i])) 1606 + continue; 1607 + clk_unprepare(fimc->clock[i]); 1608 + clk_put(fimc->clock[i]); 1609 + fimc->clock[i] = NULL; 1607 1610 } 1608 1611 } 1609 1612 1610 1613 static int fimc_clk_get(struct fimc_dev *fimc) 1611 1614 { 1612 - int i; 1615 + int i, ret; 1616 + 1613 1617 for (i = 0; i < fimc->num_clocks; i++) { 1614 1618 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]); 1615 - if (!IS_ERR_OR_NULL(fimc->clock[i])) 1616 - continue; 1617 - dev_err(&fimc->pdev->dev, "failed to get fimc clock: %s\n", 1618 - fimc_clocks[i]); 1619 - return -ENXIO; 1619 + if (IS_ERR(fimc->clock[i])) 1620 + goto err; 1621 + ret = clk_prepare(fimc->clock[i]); 1622 + if (ret < 0) { 1623 + clk_put(fimc->clock[i]); 1624 + fimc->clock[i] = NULL; 1625 + goto err; 1626 + } 1620 1627 } 1621 - 1622 1628 return 0; 1629 + err: 1630 + fimc_clk_put(fimc); 1631 + dev_err(&fimc->pdev->dev, "failed to get clock: %s\n", 1632 + fimc_clocks[i]); 1633 + return -ENXIO; 1623 1634 } 1624 1635 1625 1636 static int fimc_m2m_suspend(struct fimc_dev *fimc) ··· 1678 1667 struct s5p_platform_fimc *pdata; 1679 1668 int ret = 0; 1680 1669 1681 - dev_dbg(&pdev->dev, "%s():\n", __func__); 1682 - 1683 1670 drv_data = (struct samsung_fimc_driverdata *) 1684 1671 platform_get_device_id(pdev)->driver_data; 1685 1672 ··· 1687 1678 return -EINVAL; 1688 1679 } 1689 1680 1690 - fimc = kzalloc(sizeof(struct fimc_dev), GFP_KERNEL); 1681 + fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL); 1691 1682 if (!fimc) 1692 1683 return -ENOMEM; 1693 1684 ··· 1698 1689 pdata = pdev->dev.platform_data; 1699 1690 fimc->pdata = pdata; 1700 1691 1701 - 1702 1692 init_waitqueue_head(&fimc->irq_queue); 1703 1693 spin_lock_init(&fimc->slock); 1704 1694 mutex_init(&fimc->lock); 1705 1695 1706 1696 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1707 - if (!res) { 1708 - dev_err(&pdev->dev, "failed to find the registers\n"); 1709 - ret = -ENOENT; 1710 - goto err_info; 1711 - } 1712 - 1713 - fimc->regs_res = request_mem_region(res->start, resource_size(res), 1714 - dev_name(&pdev->dev)); 1715 - if (!fimc->regs_res) { 1716 - dev_err(&pdev->dev, "failed to obtain register region\n"); 1717 - ret = -ENOENT; 1718 - goto err_info; 1719 - } 1720 - 1721 - fimc->regs = ioremap(res->start, resource_size(res)); 1722 - if (!fimc->regs) { 1723 - dev_err(&pdev->dev, "failed to map registers\n"); 1724 - ret = -ENXIO; 1725 - goto err_req_region; 1697 + fimc->regs = devm_request_and_ioremap(&pdev->dev, res); 1698 + if (fimc->regs == NULL) { 1699 + dev_err(&pdev->dev, "Failed to obtain io memory\n"); 1700 + return -ENOENT; 1726 1701 } 1727 1702 1728 1703 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1729 - if (!res) { 1730 - dev_err(&pdev->dev, "failed to get IRQ resource\n"); 1731 - ret = -ENXIO; 1732 - goto err_regs_unmap; 1704 + if (res == NULL) { 1705 + dev_err(&pdev->dev, "Failed to get IRQ resource\n"); 1706 + return -ENXIO; 1733 1707 } 1734 1708 fimc->irq = res->start; 1735 1709 1736 1710 fimc->num_clocks = MAX_FIMC_CLOCKS; 1737 1711 ret = fimc_clk_get(fimc); 1738 1712 if (ret) 1739 - goto err_regs_unmap; 1713 + return ret; 1740 1714 clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency); 1741 1715 clk_enable(fimc->clock[CLK_BUS]); 1742 1716 1743 1717 platform_set_drvdata(pdev, fimc); 1744 1718 1745 - ret = request_irq(fimc->irq, fimc_irq_handler, 0, pdev->name, fimc); 1719 + ret = devm_request_irq(&pdev->dev, fimc->irq, fimc_irq_handler, 1720 + 0, pdev->name, fimc); 1746 1721 if (ret) { 1747 1722 dev_err(&pdev->dev, "failed to install irq (%d)\n", ret); 1748 1723 goto err_clk; ··· 1735 1742 pm_runtime_enable(&pdev->dev); 1736 1743 ret = pm_runtime_get_sync(&pdev->dev); 1737 1744 if (ret < 0) 1738 - goto err_irq; 1745 + goto err_clk; 1739 1746 /* Initialize contiguous memory allocator */ 1740 1747 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 1741 1748 if (IS_ERR(fimc->alloc_ctx)) { ··· 1750 1757 1751 1758 err_pm: 1752 1759 pm_runtime_put(&pdev->dev); 1753 - err_irq: 1754 - free_irq(fimc->irq, fimc); 1755 1760 err_clk: 1756 1761 fimc_clk_put(fimc); 1757 - err_regs_unmap: 1758 - iounmap(fimc->regs); 1759 - err_req_region: 1760 - release_resource(fimc->regs_res); 1761 - kfree(fimc->regs_res); 1762 - err_info: 1763 - kfree(fimc); 1764 1762 return ret; 1765 1763 } 1766 1764 ··· 1838 1854 1839 1855 clk_disable(fimc->clock[CLK_BUS]); 1840 1856 fimc_clk_put(fimc); 1841 - free_irq(fimc->irq, fimc); 1842 - iounmap(fimc->regs); 1843 - release_resource(fimc->regs_res); 1844 - kfree(fimc->regs_res); 1845 - kfree(fimc); 1846 1857 1847 1858 dev_info(&pdev->dev, "driver unloaded\n"); 1848 1859 return 0;
-2
drivers/media/video/s5p-fimc/fimc-core.h
··· 434 434 * @num_clocks: the number of clocks managed by this device instance 435 435 * @clock: clocks required for FIMC operation 436 436 * @regs: the mapped hardware registers 437 - * @regs_res: the resource claimed for IO registers 438 437 * @irq: FIMC interrupt number 439 438 * @irq_queue: interrupt handler waitqueue 440 439 * @v4l2_dev: root v4l2_device ··· 453 454 u16 num_clocks; 454 455 struct clk *clock[MAX_FIMC_CLOCKS]; 455 456 void __iomem *regs; 456 - struct resource *regs_res; 457 457 int irq; 458 458 wait_queue_head_t irq_queue; 459 459 struct v4l2_device *v4l2_dev;
+2 -5
drivers/media/video/s5p-fimc/fimc-mdevice.c
··· 750 750 struct fimc_md *fmd; 751 751 int ret; 752 752 753 - fmd = kzalloc(sizeof(struct fimc_md), GFP_KERNEL); 753 + fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL); 754 754 if (!fmd) 755 755 return -ENOMEM; 756 756 ··· 771 771 ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev); 772 772 if (ret < 0) { 773 773 v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); 774 - goto err1; 774 + return ret; 775 775 } 776 776 ret = media_device_register(&fmd->media_dev); 777 777 if (ret < 0) { ··· 813 813 fimc_md_unregister_entities(fmd); 814 814 err2: 815 815 v4l2_device_unregister(&fmd->v4l2_dev); 816 - err1: 817 - kfree(fmd); 818 816 return ret; 819 817 } 820 818 ··· 826 828 fimc_md_unregister_entities(fmd); 827 829 media_device_unregister(&fmd->media_dev); 828 830 fimc_md_put_clocks(fmd); 829 - kfree(fmd); 830 831 return 0; 831 832 } 832 833
+44 -67
drivers/media/video/s5p-fimc/mipi-csis.c
··· 1 1 /* 2 2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver 3 3 * 4 - * Copyright (C) 2011 Samsung Electronics Co., Ltd. 5 - * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com> 4 + * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. 5 + * Sylwester Nawrocki, <s.nawrocki@samsung.com> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify 8 8 * it under the terms of the GNU General Public License version 2 as ··· 100 100 * @pads: CSIS pads array 101 101 * @sd: v4l2_subdev associated with CSIS device instance 102 102 * @pdev: CSIS platform device 103 - * @regs_res: requested I/O register memory resource 104 103 * @regs: mmaped I/O registers memory 105 104 * @clock: CSIS clocks 106 105 * @irq: requested s5p-mipi-csis irq number ··· 112 113 struct media_pad pads[CSIS_PADS_NUM]; 113 114 struct v4l2_subdev sd; 114 115 struct platform_device *pdev; 115 - struct resource *regs_res; 116 116 void __iomem *regs; 117 117 struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES]; 118 118 struct clk *clock[NUM_CSIS_CLOCKS]; ··· 256 258 { 257 259 int i; 258 260 259 - for (i = 0; i < NUM_CSIS_CLOCKS; i++) 260 - if (!IS_ERR_OR_NULL(state->clock[i])) 261 - clk_put(state->clock[i]); 261 + for (i = 0; i < NUM_CSIS_CLOCKS; i++) { 262 + if (IS_ERR_OR_NULL(state->clock[i])) 263 + continue; 264 + clk_unprepare(state->clock[i]); 265 + clk_put(state->clock[i]); 266 + state->clock[i] = NULL; 267 + } 262 268 } 263 269 264 270 static int s5pcsis_clk_get(struct csis_state *state) 265 271 { 266 272 struct device *dev = &state->pdev->dev; 267 - int i; 273 + int i, ret; 268 274 269 275 for (i = 0; i < NUM_CSIS_CLOCKS; i++) { 270 276 state->clock[i] = clk_get(dev, csi_clock_name[i]); 271 - if (IS_ERR(state->clock[i])) { 272 - s5pcsis_clk_put(state); 273 - dev_err(dev, "failed to get clock: %s\n", 274 - csi_clock_name[i]); 275 - return -ENXIO; 277 + if (IS_ERR(state->clock[i])) 278 + goto err; 279 + ret = clk_prepare(state->clock[i]); 280 + if (ret < 0) { 281 + clk_put(state->clock[i]); 282 + state->clock[i] = NULL; 283 + goto err; 276 284 } 277 285 } 278 286 return 0; 287 + err: 288 + s5pcsis_clk_put(state); 289 + dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]); 290 + return -ENXIO; 279 291 } 280 292 281 293 static int s5pcsis_s_power(struct v4l2_subdev *sd, int on) ··· 488 480 { 489 481 struct s5p_platform_mipi_csis *pdata; 490 482 struct resource *mem_res; 491 - struct resource *regs_res; 492 483 struct csis_state *state; 493 484 int ret = -ENOMEM; 494 485 int i; 495 486 496 - state = kzalloc(sizeof(*state), GFP_KERNEL); 487 + state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL); 497 488 if (!state) 498 489 return -ENOMEM; 499 490 ··· 502 495 pdata = pdev->dev.platform_data; 503 496 if (pdata == NULL || pdata->phy_enable == NULL) { 504 497 dev_err(&pdev->dev, "Platform data not fully specified\n"); 505 - goto e_free; 498 + return -EINVAL; 506 499 } 507 500 508 501 if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) || 509 502 pdata->lanes > CSIS0_MAX_LANES) { 510 - ret = -EINVAL; 511 503 dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n", 512 504 pdata->lanes); 513 - goto e_free; 505 + return -EINVAL; 514 506 } 515 507 516 508 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 517 - if (!mem_res) { 518 - dev_err(&pdev->dev, "Failed to get IO memory region\n"); 519 - goto e_free; 509 + state->regs = devm_request_and_ioremap(&pdev->dev, mem_res); 510 + if (state->regs == NULL) { 511 + dev_err(&pdev->dev, "Failed to request and remap io memory\n"); 512 + return -ENXIO; 520 513 } 521 - 522 - regs_res = request_mem_region(mem_res->start, resource_size(mem_res), 523 - pdev->name); 524 - if (!regs_res) { 525 - dev_err(&pdev->dev, "Failed to request IO memory region\n"); 526 - goto e_free; 527 - } 528 - state->regs_res = regs_res; 529 - 530 - state->regs = ioremap(mem_res->start, resource_size(mem_res)); 531 - if (!state->regs) { 532 - dev_err(&pdev->dev, "Failed to remap IO region\n"); 533 - goto e_reqmem; 534 - } 535 - 536 - ret = s5pcsis_clk_get(state); 537 - if (ret) 538 - goto e_unmap; 539 - 540 - clk_enable(state->clock[CSIS_CLK_MUX]); 541 - if (pdata->clk_rate) 542 - clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate); 543 - else 544 - dev_WARN(&pdev->dev, "No clock frequency specified!\n"); 545 514 546 515 state->irq = platform_get_irq(pdev, 0); 547 516 if (state->irq < 0) { 548 - ret = state->irq; 549 517 dev_err(&pdev->dev, "Failed to get irq\n"); 550 - goto e_clkput; 518 + return state->irq; 551 519 } 552 520 553 521 for (i = 0; i < CSIS_NUM_SUPPLIES; i++) ··· 531 549 ret = regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES, 532 550 state->supplies); 533 551 if (ret) 552 + return ret; 553 + 554 + ret = s5pcsis_clk_get(state); 555 + if (ret) 534 556 goto e_clkput; 535 557 536 - ret = request_irq(state->irq, s5pcsis_irq_handler, 0, 537 - dev_name(&pdev->dev), state); 558 + clk_enable(state->clock[CSIS_CLK_MUX]); 559 + if (pdata->clk_rate) 560 + clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate); 561 + else 562 + dev_WARN(&pdev->dev, "No clock frequency specified!\n"); 563 + 564 + ret = devm_request_irq(&pdev->dev, state->irq, s5pcsis_irq_handler, 565 + 0, dev_name(&pdev->dev), state); 538 566 if (ret) { 539 - dev_err(&pdev->dev, "request_irq failed\n"); 567 + dev_err(&pdev->dev, "Interrupt request failed\n"); 540 568 goto e_regput; 541 569 } 542 570 ··· 565 573 ret = media_entity_init(&state->sd.entity, 566 574 CSIS_PADS_NUM, state->pads, 0); 567 575 if (ret < 0) 568 - goto e_irqfree; 576 + goto e_clkput; 569 577 570 578 /* This allows to retrieve the platform device id by the host driver */ 571 579 v4l2_set_subdevdata(&state->sd, pdev); ··· 574 582 platform_set_drvdata(pdev, &state->sd); 575 583 576 584 pm_runtime_enable(&pdev->dev); 577 - 578 585 return 0; 579 586 580 - e_irqfree: 581 - free_irq(state->irq, state); 582 587 e_regput: 583 588 regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies); 584 589 e_clkput: 585 590 clk_disable(state->clock[CSIS_CLK_MUX]); 586 591 s5pcsis_clk_put(state); 587 - e_unmap: 588 - iounmap(state->regs); 589 - e_reqmem: 590 - release_mem_region(regs_res->start, resource_size(regs_res)); 591 - e_free: 592 - kfree(state); 593 592 return ret; 594 593 } 595 594 ··· 682 699 { 683 700 struct v4l2_subdev *sd = platform_get_drvdata(pdev); 684 701 struct csis_state *state = sd_to_csis_state(sd); 685 - struct resource *res = state->regs_res; 686 702 687 703 pm_runtime_disable(&pdev->dev); 688 - s5pcsis_suspend(&pdev->dev); 704 + s5pcsis_pm_suspend(&pdev->dev, false); 689 705 clk_disable(state->clock[CSIS_CLK_MUX]); 690 706 pm_runtime_set_suspended(&pdev->dev); 691 - 692 707 s5pcsis_clk_put(state); 693 708 regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies); 694 709 695 710 media_entity_cleanup(&state->sd.entity); 696 - free_irq(state->irq, state); 697 - iounmap(state->regs); 698 - release_mem_region(res->start, resource_size(res)); 699 - kfree(state); 700 711 701 712 return 0; 702 713 }
+5
drivers/media/video/s5p-g2d/g2d-hw.c
··· 77 77 w(r, ROP4_REG); 78 78 } 79 79 80 + void g2d_set_flip(struct g2d_dev *d, u32 r) 81 + { 82 + w(r, SRC_MSK_DIRECT_REG); 83 + } 84 + 80 85 u32 g2d_cmd_stretch(u32 e) 81 86 { 82 87 e &= 1;
+50 -13
drivers/media/video/s5p-g2d/g2d.c
··· 178 178 { 179 179 struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx, 180 180 ctrl_handler); 181 + unsigned long flags; 182 + 183 + spin_lock_irqsave(&ctx->dev->ctrl_lock, flags); 181 184 switch (ctrl->id) { 182 185 case V4L2_CID_COLORFX: 183 186 if (ctrl->val == V4L2_COLORFX_NEGATIVE) ··· 188 185 else 189 186 ctx->rop = ROP4_COPY; 190 187 break; 191 - default: 192 - v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n"); 193 - return -EINVAL; 188 + 189 + case V4L2_CID_HFLIP: 190 + ctx->flip = ctx->ctrl_hflip->val | (ctx->ctrl_vflip->val << 1); 191 + break; 192 + 194 193 } 194 + spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags); 195 195 return 0; 196 196 } 197 197 ··· 206 200 { 207 201 struct g2d_dev *dev = ctx->dev; 208 202 209 - v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1); 210 - if (ctx->ctrl_handler.error) { 211 - v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); 212 - return ctx->ctrl_handler.error; 213 - } 203 + v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3); 204 + 205 + ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops, 206 + V4L2_CID_HFLIP, 0, 1, 1, 0); 207 + 208 + ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops, 209 + V4L2_CID_VFLIP, 0, 1, 1, 0); 214 210 215 211 v4l2_ctrl_new_std_menu( 216 212 &ctx->ctrl_handler, ··· 223 215 V4L2_COLORFX_NONE); 224 216 225 217 if (ctx->ctrl_handler.error) { 226 - v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); 227 - return ctx->ctrl_handler.error; 218 + int err = ctx->ctrl_handler.error; 219 + v4l2_err(&dev->v4l2_dev, "g2d_setup_ctrls failed\n"); 220 + v4l2_ctrl_handler_free(&ctx->ctrl_handler); 221 + return err; 228 222 } 223 + 224 + v4l2_ctrl_cluster(2, &ctx->ctrl_hflip); 229 225 230 226 return 0; 231 227 } ··· 559 547 struct g2d_ctx *ctx = prv; 560 548 struct g2d_dev *dev = ctx->dev; 561 549 struct vb2_buffer *src, *dst; 550 + unsigned long flags; 562 551 u32 cmd = 0; 563 552 564 553 dev->curr = ctx; ··· 570 557 clk_enable(dev->gate); 571 558 g2d_reset(dev); 572 559 560 + spin_lock_irqsave(&dev->ctrl_lock, flags); 561 + 573 562 g2d_set_src_size(dev, &ctx->in); 574 563 g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0)); 575 564 ··· 579 564 g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); 580 565 581 566 g2d_set_rop4(dev, ctx->rop); 567 + g2d_set_flip(dev, ctx->flip); 568 + 582 569 if (ctx->in.c_width != ctx->out.c_width || 583 570 ctx->in.c_height != ctx->out.c_height) 584 571 cmd |= g2d_cmd_stretch(1); 585 572 g2d_set_cmd(dev, cmd); 586 573 g2d_start(dev); 574 + 575 + spin_unlock_irqrestore(&dev->ctrl_lock, flags); 587 576 } 588 577 589 578 static irqreturn_t g2d_isr(int irq, void *prv) ··· 677 658 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 678 659 if (!dev) 679 660 return -ENOMEM; 680 - spin_lock_init(&dev->irqlock); 661 + spin_lock_init(&dev->ctrl_lock); 681 662 mutex_init(&dev->mutex); 682 663 atomic_set(&dev->num_inst, 0); 683 664 init_waitqueue_head(&dev->irq_queue); ··· 712 693 goto unmap_regs; 713 694 } 714 695 696 + ret = clk_prepare(dev->clk); 697 + if (ret) { 698 + dev_err(&pdev->dev, "failed to prepare g2d clock\n"); 699 + goto put_clk; 700 + } 701 + 715 702 dev->gate = clk_get(&pdev->dev, "fimg2d"); 716 703 if (IS_ERR_OR_NULL(dev->gate)) { 717 704 dev_err(&pdev->dev, "failed to get g2d clock gate\n"); 718 705 ret = -ENXIO; 719 - goto put_clk; 706 + goto unprep_clk; 707 + } 708 + 709 + ret = clk_prepare(dev->gate); 710 + if (ret) { 711 + dev_err(&pdev->dev, "failed to prepare g2d clock gate\n"); 712 + goto put_clk_gate; 720 713 } 721 714 722 715 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 723 716 if (!res) { 724 717 dev_err(&pdev->dev, "failed to find IRQ\n"); 725 718 ret = -ENXIO; 726 - goto put_clk_gate; 719 + goto unprep_clk_gate; 727 720 } 728 721 729 722 dev->irq = res->start; ··· 795 764 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); 796 765 rel_irq: 797 766 free_irq(dev->irq, dev); 767 + unprep_clk_gate: 768 + clk_unprepare(dev->gate); 798 769 put_clk_gate: 799 770 clk_put(dev->gate); 771 + unprep_clk: 772 + clk_unprepare(dev->clk); 800 773 put_clk: 801 774 clk_put(dev->clk); 802 775 unmap_regs: ··· 822 787 v4l2_device_unregister(&dev->v4l2_dev); 823 788 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); 824 789 free_irq(dev->irq, dev); 790 + clk_unprepare(dev->gate); 825 791 clk_put(dev->gate); 792 + clk_unprepare(dev->clk); 826 793 clk_put(dev->clk); 827 794 iounmap(dev->regs); 828 795 release_resource(dev->res_regs);
+5 -1
drivers/media/video/s5p-g2d/g2d.h
··· 20 20 struct v4l2_m2m_dev *m2m_dev; 21 21 struct video_device *vfd; 22 22 struct mutex mutex; 23 - spinlock_t irqlock; 23 + spinlock_t ctrl_lock; 24 24 atomic_t num_inst; 25 25 struct vb2_alloc_ctx *alloc_ctx; 26 26 struct resource *res_regs; ··· 57 57 struct v4l2_m2m_ctx *m2m_ctx; 58 58 struct g2d_frame in; 59 59 struct g2d_frame out; 60 + struct v4l2_ctrl *ctrl_hflip; 61 + struct v4l2_ctrl *ctrl_vflip; 60 62 struct v4l2_ctrl_handler ctrl_handler; 61 63 u32 rop; 64 + u32 flip; 62 65 }; 63 66 64 67 struct g2d_fmt { ··· 80 77 void g2d_start(struct g2d_dev *d); 81 78 void g2d_clear_int(struct g2d_dev *d); 82 79 void g2d_set_rop4(struct g2d_dev *d, u32 r); 80 + void g2d_set_flip(struct g2d_dev *d, u32 r); 83 81 u32 g2d_cmd_stretch(u32 e); 84 82 void g2d_set_cmd(struct g2d_dev *d, u32 c); 85 83
+142 -61
drivers/media/video/s5p-jpeg/jpeg-core.c
··· 32 32 33 33 static struct s5p_jpeg_fmt formats_enc[] = { 34 34 { 35 - .name = "YUV 4:2:0 planar, YCbCr", 36 - .fourcc = V4L2_PIX_FMT_YUV420, 37 - .depth = 12, 38 - .colplanes = 3, 35 + .name = "JPEG JFIF", 36 + .fourcc = V4L2_PIX_FMT_JPEG, 37 + .colplanes = 1, 39 38 .types = MEM2MEM_CAPTURE, 40 39 }, 41 40 { ··· 42 43 .fourcc = V4L2_PIX_FMT_YUYV, 43 44 .depth = 16, 44 45 .colplanes = 1, 45 - .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, 46 + .types = MEM2MEM_OUTPUT, 46 47 }, 47 48 { 48 49 .name = "RGB565", ··· 202 203 0xf9, 0xfa 203 204 }; 204 205 206 + static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c) 207 + { 208 + return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler); 209 + } 210 + 211 + static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh) 212 + { 213 + return container_of(fh, struct s5p_jpeg_ctx, fh); 214 + } 215 + 205 216 static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl, 206 217 unsigned long tab, int len) 207 218 { ··· 278 269 struct vb2_queue *dst_vq); 279 270 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode, 280 271 __u32 pixelformat); 272 + static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx); 281 273 282 274 static int s5p_jpeg_open(struct file *file) 283 275 { ··· 286 276 struct video_device *vfd = video_devdata(file); 287 277 struct s5p_jpeg_ctx *ctx; 288 278 struct s5p_jpeg_fmt *out_fmt; 279 + int ret = 0; 289 280 290 281 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 291 282 if (!ctx) 292 283 return -ENOMEM; 293 284 294 - file->private_data = ctx; 285 + v4l2_fh_init(&ctx->fh, vfd); 286 + /* Use separate control handler per file handle */ 287 + ctx->fh.ctrl_handler = &ctx->ctrl_handler; 288 + file->private_data = &ctx->fh; 289 + v4l2_fh_add(&ctx->fh); 290 + 295 291 ctx->jpeg = jpeg; 296 292 if (vfd == jpeg->vfd_encoder) { 297 293 ctx->mode = S5P_JPEG_ENCODE; ··· 307 291 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG); 308 292 } 309 293 294 + ret = s5p_jpeg_controls_create(ctx); 295 + if (ret < 0) 296 + goto error; 297 + 310 298 ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init); 311 299 if (IS_ERR(ctx->m2m_ctx)) { 312 - int err = PTR_ERR(ctx->m2m_ctx); 313 - kfree(ctx); 314 - return err; 300 + ret = PTR_ERR(ctx->m2m_ctx); 301 + goto error; 315 302 } 316 303 317 304 ctx->out_q.fmt = out_fmt; 318 305 ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV); 319 - 320 306 return 0; 307 + 308 + error: 309 + v4l2_fh_del(&ctx->fh); 310 + v4l2_fh_exit(&ctx->fh); 311 + kfree(ctx); 312 + return ret; 321 313 } 322 314 323 315 static int s5p_jpeg_release(struct file *file) 324 316 { 325 - struct s5p_jpeg_ctx *ctx = file->private_data; 317 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data); 326 318 327 319 v4l2_m2m_ctx_release(ctx->m2m_ctx); 320 + v4l2_ctrl_handler_free(&ctx->ctrl_handler); 321 + v4l2_fh_del(&ctx->fh); 322 + v4l2_fh_exit(&ctx->fh); 328 323 kfree(ctx); 329 324 330 325 return 0; ··· 344 317 static unsigned int s5p_jpeg_poll(struct file *file, 345 318 struct poll_table_struct *wait) 346 319 { 347 - struct s5p_jpeg_ctx *ctx = file->private_data; 320 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data); 348 321 349 322 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); 350 323 } 351 324 352 325 static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma) 353 326 { 354 - struct s5p_jpeg_ctx *ctx = file->private_data; 327 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data); 355 328 356 329 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); 357 330 } ··· 475 448 static int s5p_jpeg_querycap(struct file *file, void *priv, 476 449 struct v4l2_capability *cap) 477 450 { 478 - struct s5p_jpeg_ctx *ctx = priv; 451 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 479 452 480 453 if (ctx->mode == S5P_JPEG_ENCODE) { 481 454 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder", ··· 524 497 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, 525 498 struct v4l2_fmtdesc *f) 526 499 { 527 - struct s5p_jpeg_ctx *ctx; 528 - 529 - ctx = priv; 500 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 530 501 531 502 if (ctx->mode == S5P_JPEG_ENCODE) 532 503 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f, ··· 536 511 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv, 537 512 struct v4l2_fmtdesc *f) 538 513 { 539 - struct s5p_jpeg_ctx *ctx; 540 - 541 - ctx = priv; 514 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 542 515 543 516 if (ctx->mode == S5P_JPEG_ENCODE) 544 517 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f, ··· 561 538 struct vb2_queue *vq; 562 539 struct s5p_jpeg_q_data *q_data = NULL; 563 540 struct v4l2_pix_format *pix = &f->fmt.pix; 564 - struct s5p_jpeg_ctx *ct = priv; 541 + struct s5p_jpeg_ctx *ct = fh_to_ctx(priv); 565 542 566 543 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type); 567 544 if (!vq) ··· 682 659 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv, 683 660 struct v4l2_format *f) 684 661 { 662 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 685 663 struct s5p_jpeg_fmt *fmt; 686 - struct s5p_jpeg_ctx *ctx = priv; 687 664 688 665 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat); 689 666 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) { ··· 699 676 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv, 700 677 struct v4l2_format *f) 701 678 { 679 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 702 680 struct s5p_jpeg_fmt *fmt; 703 - struct s5p_jpeg_ctx *ctx = priv; 704 681 705 682 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat); 706 683 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) { ··· 751 728 if (ret) 752 729 return ret; 753 730 754 - return s5p_jpeg_s_fmt(priv, f); 731 + return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); 755 732 } 756 733 757 734 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv, ··· 763 740 if (ret) 764 741 return ret; 765 742 766 - return s5p_jpeg_s_fmt(priv, f); 743 + return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); 767 744 } 768 745 769 746 static int s5p_jpeg_reqbufs(struct file *file, void *priv, 770 747 struct v4l2_requestbuffers *reqbufs) 771 748 { 772 - struct s5p_jpeg_ctx *ctx = priv; 749 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 773 750 774 751 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); 775 752 } ··· 777 754 static int s5p_jpeg_querybuf(struct file *file, void *priv, 778 755 struct v4l2_buffer *buf) 779 756 { 780 - struct s5p_jpeg_ctx *ctx = priv; 757 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 781 758 782 759 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); 783 760 } 784 761 785 762 static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) 786 763 { 787 - struct s5p_jpeg_ctx *ctx = priv; 764 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 788 765 789 766 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); 790 767 } ··· 792 769 static int s5p_jpeg_dqbuf(struct file *file, void *priv, 793 770 struct v4l2_buffer *buf) 794 771 { 795 - struct s5p_jpeg_ctx *ctx = priv; 772 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 796 773 797 774 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); 798 775 } ··· 800 777 static int s5p_jpeg_streamon(struct file *file, void *priv, 801 778 enum v4l2_buf_type type) 802 779 { 803 - struct s5p_jpeg_ctx *ctx = priv; 780 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 804 781 805 782 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); 806 783 } ··· 808 785 static int s5p_jpeg_streamoff(struct file *file, void *priv, 809 786 enum v4l2_buf_type type) 810 787 { 811 - struct s5p_jpeg_ctx *ctx = priv; 788 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 812 789 813 790 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); 814 791 } ··· 816 793 int s5p_jpeg_g_selection(struct file *file, void *priv, 817 794 struct v4l2_selection *s) 818 795 { 819 - struct s5p_jpeg_ctx *ctx = priv; 796 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); 820 797 821 798 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 822 799 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ··· 845 822 return 0; 846 823 } 847 824 848 - static int s5p_jpeg_g_jpegcomp(struct file *file, void *priv, 849 - struct v4l2_jpegcompression *compr) 825 + /* 826 + * V4L2 controls 827 + */ 828 + 829 + static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 850 830 { 851 - struct s5p_jpeg_ctx *ctx = priv; 831 + struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); 832 + struct s5p_jpeg *jpeg = ctx->jpeg; 833 + unsigned long flags; 852 834 853 - if (ctx->mode == S5P_JPEG_DECODE) 854 - return -ENOTTY; 835 + switch (ctrl->id) { 836 + case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: 837 + spin_lock_irqsave(&jpeg->slock, flags); 855 838 856 - memset(compr, 0, sizeof(*compr)); 857 - compr->quality = ctx->compr_quality; 839 + WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY); 840 + if (ctx->subsampling > 2) 841 + ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; 842 + else 843 + ctrl->val = ctx->subsampling; 844 + spin_unlock_irqrestore(&jpeg->slock, flags); 845 + break; 846 + } 858 847 859 848 return 0; 860 849 } 861 850 862 - static int s5p_jpeg_s_jpegcomp(struct file *file, void *priv, 863 - struct v4l2_jpegcompression *compr) 851 + static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl) 864 852 { 865 - struct s5p_jpeg_ctx *ctx = priv; 853 + struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); 854 + unsigned long flags; 855 + 856 + spin_lock_irqsave(&ctx->jpeg->slock, flags); 857 + 858 + switch (ctrl->id) { 859 + case V4L2_CID_JPEG_COMPRESSION_QUALITY: 860 + ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - ctrl->val; 861 + break; 862 + case V4L2_CID_JPEG_RESTART_INTERVAL: 863 + ctx->restart_interval = ctrl->val; 864 + break; 865 + case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: 866 + ctx->subsampling = ctrl->val; 867 + break; 868 + } 869 + 870 + spin_unlock_irqrestore(&ctx->jpeg->slock, flags); 871 + return 0; 872 + } 873 + 874 + static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = { 875 + .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl, 876 + .s_ctrl = s5p_jpeg_s_ctrl, 877 + }; 878 + 879 + static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx) 880 + { 881 + unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */ 882 + struct v4l2_ctrl *ctrl; 883 + 884 + v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3); 885 + 886 + if (ctx->mode == S5P_JPEG_ENCODE) { 887 + v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops, 888 + V4L2_CID_JPEG_COMPRESSION_QUALITY, 889 + 0, 3, 1, 3); 890 + 891 + v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops, 892 + V4L2_CID_JPEG_RESTART_INTERVAL, 893 + 0, 3, 0xffff, 0); 894 + mask = ~0x06; /* 422, 420 */ 895 + } 896 + 897 + ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops, 898 + V4L2_CID_JPEG_CHROMA_SUBSAMPLING, 899 + V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask, 900 + V4L2_JPEG_CHROMA_SUBSAMPLING_422); 901 + 902 + if (ctx->ctrl_handler.error) 903 + return ctx->ctrl_handler.error; 866 904 867 905 if (ctx->mode == S5P_JPEG_DECODE) 868 - return -ENOTTY; 869 - 870 - compr->quality = clamp(compr->quality, S5P_JPEG_COMPR_QUAL_BEST, 871 - S5P_JPEG_COMPR_QUAL_WORST); 872 - 873 - ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - compr->quality; 874 - 906 + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE | 907 + V4L2_CTRL_FLAG_READ_ONLY; 875 908 return 0; 876 909 } 877 910 ··· 956 877 .vidioc_streamoff = s5p_jpeg_streamoff, 957 878 958 879 .vidioc_g_selection = s5p_jpeg_g_selection, 959 - 960 - .vidioc_g_jpegcomp = s5p_jpeg_g_jpegcomp, 961 - .vidioc_s_jpegcomp = s5p_jpeg_s_jpegcomp, 962 880 }; 963 881 964 882 /* ··· 984 908 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565); 985 909 else 986 910 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422); 987 - if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV) 988 - jpeg_subsampling_mode(jpeg->regs, 989 - S5P_JPEG_SUBSAMPLING_422); 990 - else 991 - jpeg_subsampling_mode(jpeg->regs, 992 - S5P_JPEG_SUBSAMPLING_420); 993 - jpeg_dri(jpeg->regs, 0); 911 + jpeg_subsampling_mode(jpeg->regs, ctx->subsampling); 912 + jpeg_dri(jpeg->regs, ctx->restart_interval); 994 913 jpeg_x(jpeg->regs, ctx->out_q.w); 995 914 jpeg_y(jpeg->regs, ctx->out_q.h); 996 915 jpeg_imgadr(jpeg->regs, src_addr); ··· 1024 953 jpeg_htbl_dc(jpeg->regs, 2); 1025 954 jpeg_htbl_ac(jpeg->regs, 3); 1026 955 jpeg_htbl_dc(jpeg->regs, 3); 1027 - } else { 956 + } else { /* S5P_JPEG_DECODE */ 1028 957 jpeg_rst_int_enable(jpeg->regs, true); 1029 958 jpeg_data_num_int_enable(jpeg->regs, true); 1030 959 jpeg_final_mcu_num_int_enable(jpeg->regs, true); 1031 - jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422); 960 + if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV) 961 + jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422); 962 + else 963 + jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420); 1032 964 jpeg_jpgadr(jpeg->regs, src_addr); 1033 965 jpeg_imgadr(jpeg->regs, dst_addr); 1034 966 } 967 + 1035 968 jpeg_start(jpeg->regs); 1036 969 } 1037 970 ··· 1237 1162 bool timer_elapsed = false; 1238 1163 bool op_completed = false; 1239 1164 1165 + spin_lock(&jpeg->slock); 1166 + 1240 1167 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); 1241 1168 1242 1169 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx); ··· 1269 1192 v4l2_m2m_buf_done(dst_buf, state); 1270 1193 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx); 1271 1194 1195 + curr_ctx->subsampling = jpeg_get_subsampling_mode(jpeg->regs); 1196 + spin_unlock(&jpeg->slock); 1197 + 1272 1198 jpeg_clear_int(jpeg->regs); 1273 1199 1274 1200 return IRQ_HANDLED; ··· 1295 1215 return -ENOMEM; 1296 1216 1297 1217 mutex_init(&jpeg->lock); 1218 + spin_lock_init(&jpeg->slock); 1298 1219 jpeg->dev = &pdev->dev; 1299 1220 1300 1221 /* memory-mapped registers */
+10 -1
drivers/media/video/s5p-jpeg/jpeg-core.h
··· 14 14 #define JPEG_CORE_H_ 15 15 16 16 #include <media/v4l2-device.h> 17 + #include <media/v4l2-fh.h> 18 + #include <media/v4l2-ctrls.h> 17 19 18 20 #define S5P_JPEG_M2M_NAME "s5p-jpeg" 19 21 ··· 49 47 /** 50 48 * struct s5p_jpeg - JPEG IP abstraction 51 49 * @lock: the mutex protecting this structure 50 + * @slock: spinlock protecting the device contexts 52 51 * @v4l2_dev: v4l2 device for mem2mem mode 53 52 * @vfd_encoder: video device node for encoder mem2mem mode 54 53 * @vfd_decoder: video device node for decoder mem2mem mode ··· 63 60 */ 64 61 struct s5p_jpeg { 65 62 struct mutex lock; 63 + struct spinlock slock; 66 64 67 65 struct v4l2_device v4l2_dev; 68 66 struct video_device *vfd_encoder; ··· 121 117 * @out_q: source (output) queue information 122 118 * @cap_fmt: destination (capture) queue queue information 123 119 * @hdr_parsed: set if header has been parsed during decompression 120 + * @ctrl_handler: controls handler 124 121 */ 125 122 struct s5p_jpeg_ctx { 126 123 struct s5p_jpeg *jpeg; 127 124 unsigned int mode; 128 - unsigned int compr_quality; 125 + unsigned short compr_quality; 126 + unsigned short restart_interval; 127 + unsigned short subsampling; 129 128 struct v4l2_m2m_ctx *m2m_ctx; 130 129 struct s5p_jpeg_q_data out_q; 131 130 struct s5p_jpeg_q_data cap_q; 131 + struct v4l2_fh fh; 132 132 bool hdr_parsed; 133 + struct v4l2_ctrl_handler ctrl_handler; 133 134 }; 134 135 135 136 /**
+11 -7
drivers/media/video/s5p-jpeg/jpeg-hw.h
··· 13 13 #define JPEG_HW_H_ 14 14 15 15 #include <linux/io.h> 16 + #include <linux/videodev2.h> 16 17 17 18 #include "jpeg-hw.h" 18 19 #include "jpeg-regs.h" ··· 26 25 #define S5P_JPEG_DECODE 1 27 26 #define S5P_JPEG_RAW_IN_565 0 28 27 #define S5P_JPEG_RAW_IN_422 1 29 - #define S5P_JPEG_SUBSAMPLING_422 0 30 - #define S5P_JPEG_SUBSAMPLING_420 1 31 28 #define S5P_JPEG_RAW_OUT_422 0 32 29 #define S5P_JPEG_RAW_OUT_420 1 33 30 ··· 90 91 writel(reg, regs + S5P_JPGMOD); 91 92 } 92 93 93 - static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned long mode) 94 + static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned int mode) 94 95 { 95 96 unsigned long reg, m; 96 97 97 - m = S5P_SUBSAMPLING_MODE_422; 98 - if (mode == S5P_JPEG_SUBSAMPLING_422) 99 - m = S5P_SUBSAMPLING_MODE_422; 100 - else if (mode == S5P_JPEG_SUBSAMPLING_420) 98 + if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420) 101 99 m = S5P_SUBSAMPLING_MODE_420; 100 + else 101 + m = S5P_SUBSAMPLING_MODE_422; 102 + 102 103 reg = readl(regs + S5P_JPGMOD); 103 104 reg &= ~S5P_SUBSAMPLING_MODE_MASK; 104 105 reg |= m; 105 106 writel(reg, regs + S5P_JPGMOD); 107 + } 108 + 109 + static inline unsigned int jpeg_get_subsampling_mode(void __iomem *regs) 110 + { 111 + return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK; 106 112 } 107 113 108 114 static inline void jpeg_dri(void __iomem *regs, unsigned int dri)
+22 -2
drivers/media/video/s5p-mfc/s5p_mfc_pm.c
··· 41 41 pm->clock_gate = clk_get(&dev->plat_dev->dev, MFC_GATE_CLK_NAME); 42 42 if (IS_ERR(pm->clock_gate)) { 43 43 mfc_err("Failed to get clock-gating control\n"); 44 - ret = -ENOENT; 44 + ret = PTR_ERR(pm->clock_gate); 45 45 goto err_g_ip_clk; 46 46 } 47 + 48 + ret = clk_prepare(pm->clock_gate); 49 + if (ret) { 50 + mfc_err("Failed to preapre clock-gating control\n"); 51 + goto err_p_ip_clk; 52 + } 53 + 47 54 pm->clock = clk_get(&dev->plat_dev->dev, MFC_CLKNAME); 48 55 if (IS_ERR(pm->clock)) { 49 56 mfc_err("Failed to get MFC clock\n"); 50 - ret = -ENOENT; 57 + ret = PTR_ERR(pm->clock); 51 58 goto err_g_ip_clk_2; 52 59 } 60 + 61 + ret = clk_prepare(pm->clock); 62 + if (ret) { 63 + mfc_err("Failed to prepare MFC clock\n"); 64 + goto err_p_ip_clk_2; 65 + } 66 + 53 67 atomic_set(&pm->power, 0); 54 68 #ifdef CONFIG_PM_RUNTIME 55 69 pm->device = &dev->plat_dev->dev; ··· 73 59 atomic_set(&clk_ref, 0); 74 60 #endif 75 61 return 0; 62 + err_p_ip_clk_2: 63 + clk_put(pm->clock); 76 64 err_g_ip_clk_2: 65 + clk_unprepare(pm->clock_gate); 66 + err_p_ip_clk: 77 67 clk_put(pm->clock_gate); 78 68 err_g_ip_clk: 79 69 return ret; ··· 85 67 86 68 void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) 87 69 { 70 + clk_unprepare(pm->clock_gate); 88 71 clk_put(pm->clock_gate); 72 + clk_unprepare(pm->clock); 89 73 clk_put(pm->clock); 90 74 #ifdef CONFIG_PM_RUNTIME 91 75 pm_runtime_disable(pm->device);
+10
drivers/media/video/s5p-tv/Kconfig
··· 46 46 as module. It is an I2C driver, that exposes a V4L2 47 47 subdev for use by other drivers. 48 48 49 + config VIDEO_SAMSUNG_S5P_SII9234 50 + tristate "Samsung SII9234 Driver" 51 + depends on VIDEO_DEV && VIDEO_V4L2 && I2C 52 + depends on VIDEO_SAMSUNG_S5P_TV 53 + help 54 + Say Y here if you want support for the MHL interface 55 + in S5P Samsung SoC. The driver can be compiled 56 + as module. It is an I2C driver, that exposes a V4L2 57 + subdev for use by other drivers. 58 + 49 59 config VIDEO_SAMSUNG_S5P_SDO 50 60 tristate "Samsung Analog TV Driver" 51 61 depends on VIDEO_DEV && VIDEO_V4L2
+2
drivers/media/video/s5p-tv/Makefile
··· 8 8 9 9 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMIPHY) += s5p-hdmiphy.o 10 10 s5p-hdmiphy-y += hdmiphy_drv.o 11 + obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SII9234) += s5p-sii9234.o 12 + s5p-sii9234-y += sii9234_drv.o 11 13 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMI) += s5p-hdmi.o 12 14 s5p-hdmi-y += hdmi_drv.o 13 15 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SDO) += s5p-sdo.o
+72 -48
drivers/media/video/s5p-tv/hdmi_drv.c
··· 30 30 #include <linux/clk.h> 31 31 #include <linux/regulator/consumer.h> 32 32 33 + #include <media/s5p_hdmi.h> 33 34 #include <media/v4l2-common.h> 34 35 #include <media/v4l2-dev.h> 35 36 #include <media/v4l2-device.h> ··· 67 66 struct v4l2_device v4l2_dev; 68 67 /** subdev of HDMIPHY interface */ 69 68 struct v4l2_subdev *phy_sd; 69 + /** subdev of MHL interface */ 70 + struct v4l2_subdev *mhl_sd; 70 71 /** configuration of current graphic mode */ 71 72 const struct hdmi_preset_conf *cur_conf; 72 73 /** current preset */ 73 74 u32 cur_preset; 74 75 /** other resources */ 75 76 struct hdmi_resources res; 76 - }; 77 - 78 - struct hdmi_driver_data { 79 - int hdmiphy_bus; 80 77 }; 81 78 82 79 struct hdmi_tg_regs { ··· 128 129 struct v4l2_mbus_framefmt mbus_fmt; 129 130 }; 130 131 131 - /* I2C module and id for HDMIPHY */ 132 - static struct i2c_board_info hdmiphy_info = { 133 - I2C_BOARD_INFO("hdmiphy", 0x38), 134 - }; 135 - 136 - static struct hdmi_driver_data hdmi_driver_data[] = { 137 - { .hdmiphy_bus = 3 }, 138 - { .hdmiphy_bus = 8 }, 139 - }; 140 - 141 132 static struct platform_device_id hdmi_driver_types[] = { 142 133 { 143 134 .name = "s5pv210-hdmi", 144 - .driver_data = (unsigned long)&hdmi_driver_data[0], 145 135 }, { 146 136 .name = "exynos4-hdmi", 147 - .driver_data = (unsigned long)&hdmi_driver_data[1], 148 137 }, { 149 138 /* end node */ 150 139 } ··· 574 587 if (tries == 0) { 575 588 dev_err(dev, "hdmiphy's pll could not reach steady state.\n"); 576 589 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); 577 - hdmi_dumpregs(hdev, "s_stream"); 590 + hdmi_dumpregs(hdev, "hdmiphy - s_stream"); 591 + return -EIO; 592 + } 593 + 594 + /* starting MHL */ 595 + ret = v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 1); 596 + if (hdev->mhl_sd && ret) { 597 + v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); 598 + hdmi_dumpregs(hdev, "mhl - s_stream"); 578 599 return -EIO; 579 600 } 580 601 ··· 613 618 clk_set_parent(res->sclk_hdmi, res->sclk_pixel); 614 619 clk_enable(res->sclk_hdmi); 615 620 621 + v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 0); 616 622 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); 617 623 618 624 hdmi_dumpregs(hdev, "streamoff"); ··· 735 739 struct hdmi_device *hdev = sd_to_hdmi_dev(sd); 736 740 737 741 dev_dbg(dev, "%s\n", __func__); 742 + v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0); 738 743 hdmi_resource_poweroff(&hdev->res); 739 744 return 0; 740 745 } ··· 752 755 753 756 ret = hdmi_conf_apply(hdev); 754 757 if (ret) 758 + goto fail; 759 + 760 + /* starting MHL */ 761 + ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1); 762 + if (hdev->mhl_sd && ret) 755 763 goto fail; 756 764 757 765 dev_dbg(dev, "poweron succeed\n"); ··· 869 867 { 870 868 struct device *dev = &pdev->dev; 871 869 struct resource *res; 872 - struct i2c_adapter *phy_adapter; 870 + struct i2c_adapter *adapter; 873 871 struct v4l2_subdev *sd; 874 872 struct hdmi_device *hdmi_dev = NULL; 875 - struct hdmi_driver_data *drv_data; 873 + struct s5p_hdmi_platform_data *pdata = dev->platform_data; 876 874 int ret; 877 875 878 876 dev_dbg(dev, "probe start\n"); 879 877 880 - hdmi_dev = kzalloc(sizeof(*hdmi_dev), GFP_KERNEL); 878 + if (!pdata) { 879 + dev_err(dev, "platform data is missing\n"); 880 + ret = -ENODEV; 881 + goto fail; 882 + } 883 + 884 + hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(*hdmi_dev), GFP_KERNEL); 881 885 if (!hdmi_dev) { 882 886 dev_err(dev, "out of memory\n"); 883 887 ret = -ENOMEM; ··· 894 886 895 887 ret = hdmi_resources_init(hdmi_dev); 896 888 if (ret) 897 - goto fail_hdev; 889 + goto fail; 898 890 899 891 /* mapping HDMI registers */ 900 892 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ··· 904 896 goto fail_init; 905 897 } 906 898 907 - hdmi_dev->regs = ioremap(res->start, resource_size(res)); 899 + hdmi_dev->regs = devm_ioremap(&pdev->dev, res->start, 900 + resource_size(res)); 908 901 if (hdmi_dev->regs == NULL) { 909 902 dev_err(dev, "register mapping failed.\n"); 910 903 ret = -ENXIO; 911 - goto fail_hdev; 904 + goto fail_init; 912 905 } 913 906 914 907 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 915 908 if (res == NULL) { 916 909 dev_err(dev, "get interrupt resource failed.\n"); 917 910 ret = -ENXIO; 918 - goto fail_regs; 911 + goto fail_init; 919 912 } 920 913 921 - ret = request_irq(res->start, hdmi_irq_handler, 0, "hdmi", hdmi_dev); 914 + ret = devm_request_irq(&pdev->dev, res->start, hdmi_irq_handler, 0, 915 + "hdmi", hdmi_dev); 922 916 if (ret) { 923 917 dev_err(dev, "request interrupt failed.\n"); 924 - goto fail_regs; 918 + goto fail_init; 925 919 } 926 920 hdmi_dev->irq = res->start; 927 921 ··· 934 924 ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev); 935 925 if (ret) { 936 926 dev_err(dev, "could not register v4l2 device.\n"); 937 - goto fail_irq; 927 + goto fail_init; 938 928 } 939 929 940 - drv_data = (struct hdmi_driver_data *) 941 - platform_get_device_id(pdev)->driver_data; 942 - phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus); 943 - if (phy_adapter == NULL) { 944 - dev_err(dev, "adapter request failed\n"); 930 + /* testing if hdmiphy info is present */ 931 + if (!pdata->hdmiphy_info) { 932 + dev_err(dev, "hdmiphy info is missing in platform data\n"); 933 + ret = -ENXIO; 934 + goto fail_vdev; 935 + } 936 + 937 + adapter = i2c_get_adapter(pdata->hdmiphy_bus); 938 + if (adapter == NULL) { 939 + dev_err(dev, "hdmiphy adapter request failed\n"); 945 940 ret = -ENXIO; 946 941 goto fail_vdev; 947 942 } 948 943 949 944 hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev, 950 - phy_adapter, &hdmiphy_info, NULL); 945 + adapter, pdata->hdmiphy_info, NULL); 951 946 /* on failure or not adapter is no longer useful */ 952 - i2c_put_adapter(phy_adapter); 947 + i2c_put_adapter(adapter); 953 948 if (hdmi_dev->phy_sd == NULL) { 954 949 dev_err(dev, "missing subdev for hdmiphy\n"); 955 950 ret = -ENODEV; 956 951 goto fail_vdev; 952 + } 953 + 954 + /* initialization of MHL interface if present */ 955 + if (pdata->mhl_info) { 956 + adapter = i2c_get_adapter(pdata->mhl_bus); 957 + if (adapter == NULL) { 958 + dev_err(dev, "MHL adapter request failed\n"); 959 + ret = -ENXIO; 960 + goto fail_vdev; 961 + } 962 + 963 + hdmi_dev->mhl_sd = v4l2_i2c_new_subdev_board( 964 + &hdmi_dev->v4l2_dev, adapter, 965 + pdata->mhl_info, NULL); 966 + /* on failure or not adapter is no longer useful */ 967 + i2c_put_adapter(adapter); 968 + if (hdmi_dev->mhl_sd == NULL) { 969 + dev_err(dev, "missing subdev for MHL\n"); 970 + ret = -ENODEV; 971 + goto fail_vdev; 972 + } 957 973 } 958 974 959 975 clk_enable(hdmi_dev->res.hdmi); ··· 998 962 /* storing subdev for call that have only access to struct device */ 999 963 dev_set_drvdata(dev, sd); 1000 964 1001 - dev_info(dev, "probe sucessful\n"); 965 + dev_info(dev, "probe successful\n"); 1002 966 1003 967 return 0; 1004 968 1005 969 fail_vdev: 1006 970 v4l2_device_unregister(&hdmi_dev->v4l2_dev); 1007 971 1008 - fail_irq: 1009 - free_irq(hdmi_dev->irq, hdmi_dev); 1010 - 1011 - fail_regs: 1012 - iounmap(hdmi_dev->regs); 1013 - 1014 972 fail_init: 1015 973 hdmi_resources_cleanup(hdmi_dev); 1016 - 1017 - fail_hdev: 1018 - kfree(hdmi_dev); 1019 974 1020 975 fail: 1021 976 dev_err(dev, "probe failed\n"); ··· 1023 996 clk_disable(hdmi_dev->res.hdmi); 1024 997 v4l2_device_unregister(&hdmi_dev->v4l2_dev); 1025 998 disable_irq(hdmi_dev->irq); 1026 - free_irq(hdmi_dev->irq, hdmi_dev); 1027 - iounmap(hdmi_dev->regs); 1028 999 hdmi_resources_cleanup(hdmi_dev); 1029 - kfree(hdmi_dev); 1030 - dev_info(dev, "remove sucessful\n"); 1000 + dev_info(dev, "remove successful\n"); 1031 1001 1032 1002 return 0; 1033 1003 }
+1 -11
drivers/media/video/s5p-tv/hdmiphy_drv.c
··· 175 175 .id_table = hdmiphy_id, 176 176 }; 177 177 178 - static int __init hdmiphy_init(void) 179 - { 180 - return i2c_add_driver(&hdmiphy_driver); 181 - } 182 - module_init(hdmiphy_init); 183 - 184 - static void __exit hdmiphy_exit(void) 185 - { 186 - i2c_del_driver(&hdmiphy_driver); 187 - } 188 - module_exit(hdmiphy_exit); 178 + module_i2c_driver(hdmiphy_driver);
+1 -1
drivers/media/video/s5p-tv/mixer_drv.c
··· 444 444 445 445 kfree(mdev); 446 446 447 - dev_info(dev, "remove sucessful\n"); 447 + dev_info(dev, "remove successful\n"); 448 448 return 0; 449 449 } 450 450
+9 -17
drivers/media/video/s5p-tv/sdo_drv.c
··· 301 301 struct clk *sclk_vpll; 302 302 303 303 dev_info(dev, "probe start\n"); 304 - sdev = kzalloc(sizeof *sdev, GFP_KERNEL); 304 + sdev = devm_kzalloc(&pdev->dev, sizeof *sdev, GFP_KERNEL); 305 305 if (!sdev) { 306 306 dev_err(dev, "not enough memory.\n"); 307 307 ret = -ENOMEM; ··· 314 314 if (res == NULL) { 315 315 dev_err(dev, "get memory resource failed.\n"); 316 316 ret = -ENXIO; 317 - goto fail_sdev; 317 + goto fail; 318 318 } 319 319 320 - sdev->regs = ioremap(res->start, resource_size(res)); 320 + sdev->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 321 321 if (sdev->regs == NULL) { 322 322 dev_err(dev, "register mapping failed.\n"); 323 323 ret = -ENXIO; 324 - goto fail_sdev; 324 + goto fail; 325 325 } 326 326 327 327 /* acquiring interrupt */ ··· 329 329 if (res == NULL) { 330 330 dev_err(dev, "get interrupt resource failed.\n"); 331 331 ret = -ENXIO; 332 - goto fail_regs; 332 + goto fail; 333 333 } 334 - ret = request_irq(res->start, sdo_irq_handler, 0, "s5p-sdo", sdev); 334 + ret = devm_request_irq(&pdev->dev, res->start, sdo_irq_handler, 0, 335 + "s5p-sdo", sdev); 335 336 if (ret) { 336 337 dev_err(dev, "request interrupt failed.\n"); 337 - goto fail_regs; 338 + goto fail; 338 339 } 339 340 sdev->irq = res->start; 340 341 ··· 344 343 if (IS_ERR_OR_NULL(sdev->sclk_dac)) { 345 344 dev_err(dev, "failed to get clock 'sclk_dac'\n"); 346 345 ret = -ENXIO; 347 - goto fail_irq; 346 + goto fail; 348 347 } 349 348 sdev->dac = clk_get(dev, "dac"); 350 349 if (IS_ERR_OR_NULL(sdev->dac)) { ··· 416 415 clk_put(sdev->dac); 417 416 fail_sclk_dac: 418 417 clk_put(sdev->sclk_dac); 419 - fail_irq: 420 - free_irq(sdev->irq, sdev); 421 - fail_regs: 422 - iounmap(sdev->regs); 423 - fail_sdev: 424 - kfree(sdev); 425 418 fail: 426 419 dev_info(dev, "probe failed\n"); 427 420 return ret; ··· 434 439 clk_put(sdev->dacphy); 435 440 clk_put(sdev->dac); 436 441 clk_put(sdev->sclk_dac); 437 - free_irq(sdev->irq, sdev); 438 - iounmap(sdev->regs); 439 - kfree(sdev); 440 442 441 443 dev_info(&pdev->dev, "remove successful\n"); 442 444 return 0;
+432
drivers/media/video/s5p-tv/sii9234_drv.c
··· 1 + /* 2 + * Samsung MHL interface driver 3 + * 4 + * Copyright (C) 2011 Samsung Electronics Co.Ltd 5 + * Author: Tomasz Stanislawski <t.stanislaws@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the 9 + * Free Software Foundation; either version 2 of the License, or (at your 10 + * option) any later version. 11 + */ 12 + 13 + #include <linux/delay.h> 14 + #include <linux/err.h> 15 + #include <linux/freezer.h> 16 + #include <linux/gpio.h> 17 + #include <linux/i2c.h> 18 + #include <linux/interrupt.h> 19 + #include <linux/irq.h> 20 + #include <linux/kthread.h> 21 + #include <linux/module.h> 22 + #include <linux/pm_runtime.h> 23 + #include <linux/regulator/machine.h> 24 + #include <linux/slab.h> 25 + 26 + #include <mach/gpio.h> 27 + #include <plat/gpio-cfg.h> 28 + 29 + #include <media/sii9234.h> 30 + #include <media/v4l2-subdev.h> 31 + 32 + MODULE_AUTHOR("Tomasz Stanislawski <t.stanislaws@samsung.com>"); 33 + MODULE_DESCRIPTION("Samsung MHL interface driver"); 34 + MODULE_LICENSE("GPL"); 35 + 36 + struct sii9234_context { 37 + struct i2c_client *client; 38 + struct regulator *power; 39 + int gpio_n_reset; 40 + struct v4l2_subdev sd; 41 + }; 42 + 43 + static inline struct sii9234_context *sd_to_context(struct v4l2_subdev *sd) 44 + { 45 + return container_of(sd, struct sii9234_context, sd); 46 + } 47 + 48 + static inline int sii9234_readb(struct i2c_client *client, int addr) 49 + { 50 + return i2c_smbus_read_byte_data(client, addr); 51 + } 52 + 53 + static inline int sii9234_writeb(struct i2c_client *client, int addr, int value) 54 + { 55 + return i2c_smbus_write_byte_data(client, addr, value); 56 + } 57 + 58 + static inline int sii9234_writeb_mask(struct i2c_client *client, int addr, 59 + int value, int mask) 60 + { 61 + int ret; 62 + 63 + ret = i2c_smbus_read_byte_data(client, addr); 64 + if (ret < 0) 65 + return ret; 66 + ret = (ret & ~mask) | (value & mask); 67 + return i2c_smbus_write_byte_data(client, addr, ret); 68 + } 69 + 70 + static inline int sii9234_readb_idx(struct i2c_client *client, int addr) 71 + { 72 + int ret; 73 + ret = i2c_smbus_write_byte_data(client, 0xbc, addr >> 8); 74 + if (ret < 0) 75 + return ret; 76 + ret = i2c_smbus_write_byte_data(client, 0xbd, addr & 0xff); 77 + if (ret < 0) 78 + return ret; 79 + return i2c_smbus_read_byte_data(client, 0xbe); 80 + } 81 + 82 + static inline int sii9234_writeb_idx(struct i2c_client *client, int addr, 83 + int value) 84 + { 85 + int ret; 86 + ret = i2c_smbus_write_byte_data(client, 0xbc, addr >> 8); 87 + if (ret < 0) 88 + return ret; 89 + ret = i2c_smbus_write_byte_data(client, 0xbd, addr & 0xff); 90 + if (ret < 0) 91 + return ret; 92 + ret = i2c_smbus_write_byte_data(client, 0xbe, value); 93 + return ret; 94 + } 95 + 96 + static inline int sii9234_writeb_idx_mask(struct i2c_client *client, int addr, 97 + int value, int mask) 98 + { 99 + int ret; 100 + 101 + ret = sii9234_readb_idx(client, addr); 102 + if (ret < 0) 103 + return ret; 104 + ret = (ret & ~mask) | (value & mask); 105 + return sii9234_writeb_idx(client, addr, ret); 106 + } 107 + 108 + static int sii9234_reset(struct sii9234_context *ctx) 109 + { 110 + struct i2c_client *client = ctx->client; 111 + struct device *dev = &client->dev; 112 + int ret, tries; 113 + 114 + gpio_direction_output(ctx->gpio_n_reset, 1); 115 + mdelay(1); 116 + gpio_direction_output(ctx->gpio_n_reset, 0); 117 + mdelay(1); 118 + gpio_direction_output(ctx->gpio_n_reset, 1); 119 + mdelay(1); 120 + 121 + /* going to TTPI mode */ 122 + ret = sii9234_writeb(client, 0xc7, 0); 123 + if (ret < 0) { 124 + dev_err(dev, "failed to set TTPI mode\n"); 125 + return ret; 126 + } 127 + for (tries = 0; tries < 100 ; ++tries) { 128 + ret = sii9234_readb(client, 0x1b); 129 + if (ret > 0) 130 + break; 131 + if (ret < 0) { 132 + dev_err(dev, "failed to reset device\n"); 133 + return -EIO; 134 + } 135 + mdelay(1); 136 + } 137 + if (tries == 100) { 138 + dev_err(dev, "maximal number of tries reached\n"); 139 + return -EIO; 140 + } 141 + 142 + return 0; 143 + } 144 + 145 + static int sii9234_verify_version(struct i2c_client *client) 146 + { 147 + struct device *dev = &client->dev; 148 + int family, rev, tpi_rev, dev_id, sub_id, hdcp, id; 149 + 150 + family = sii9234_readb(client, 0x1b); 151 + rev = sii9234_readb(client, 0x1c) & 0x0f; 152 + tpi_rev = sii9234_readb(client, 0x1d) & 0x7f; 153 + dev_id = sii9234_readb_idx(client, 0x0103); 154 + sub_id = sii9234_readb_idx(client, 0x0102); 155 + hdcp = sii9234_readb(client, 0x30); 156 + 157 + if (family < 0 || rev < 0 || tpi_rev < 0 || dev_id < 0 || 158 + sub_id < 0 || hdcp < 0) { 159 + dev_err(dev, "failed to read chip's version\n"); 160 + return -EIO; 161 + } 162 + 163 + id = (dev_id << 8) | sub_id; 164 + 165 + dev_info(dev, "chip: SiL%02x family: %02x, rev: %02x\n", 166 + id, family, rev); 167 + dev_info(dev, "tpi_rev:%02x, hdcp: %02x\n", tpi_rev, hdcp); 168 + if (id != 0x9234) { 169 + dev_err(dev, "not supported chip\n"); 170 + return -ENODEV; 171 + } 172 + 173 + return 0; 174 + } 175 + 176 + static u8 data[][3] = { 177 + /* setup from driver created by doonsoo45.kim */ 178 + { 0x01, 0x05, 0x04 }, /* Enable Auto soft reset on SCDT = 0 */ 179 + { 0x01, 0x08, 0x35 }, /* Power Up TMDS Tx Core */ 180 + { 0x01, 0x0d, 0x1c }, /* HDMI Transcode mode enable */ 181 + { 0x01, 0x2b, 0x01 }, /* Enable HDCP Compliance workaround */ 182 + { 0x01, 0x79, 0x40 }, /* daniel test...MHL_INT */ 183 + { 0x01, 0x80, 0x34 }, /* Enable Rx PLL Clock Value */ 184 + { 0x01, 0x90, 0x27 }, /* Enable CBUS discovery */ 185 + { 0x01, 0x91, 0xe5 }, /* Skip RGND detection */ 186 + { 0x01, 0x92, 0x46 }, /* Force MHD mode */ 187 + { 0x01, 0x93, 0xdc }, /* Disable CBUS pull-up during RGND measurement */ 188 + { 0x01, 0x94, 0x66 }, /* 1.8V CBUS VTH & GND threshold */ 189 + { 0x01, 0x95, 0x31 }, /* RGND block & single discovery attempt */ 190 + { 0x01, 0x96, 0x22 }, /* use 1K and 2K setting */ 191 + { 0x01, 0xa0, 0x10 }, /* SIMG: Term mode */ 192 + { 0x01, 0xa1, 0xfc }, /* Disable internal Mobile HD driver */ 193 + { 0x01, 0xa3, 0xfa }, /* SIMG: Output Swing default EB, 3x Clk Mult */ 194 + { 0x01, 0xa5, 0x80 }, /* SIMG: RGND Hysterisis, 3x mode for Beast */ 195 + { 0x01, 0xa6, 0x0c }, /* SIMG: Swing Offset */ 196 + { 0x02, 0x3d, 0x3f }, /* Power up CVCC 1.2V core */ 197 + { 0x03, 0x00, 0x00 }, /* SIMG: correcting HW default */ 198 + { 0x03, 0x11, 0x01 }, /* Enable TxPLL Clock */ 199 + { 0x03, 0x12, 0x15 }, /* Enable Tx Clock Path & Equalizer */ 200 + { 0x03, 0x13, 0x60 }, /* SIMG: Set termination value */ 201 + { 0x03, 0x14, 0xf0 }, /* SIMG: Change CKDT level */ 202 + { 0x03, 0x17, 0x07 }, /* SIMG: PLL Calrefsel */ 203 + { 0x03, 0x1a, 0x20 }, /* VCO Cal */ 204 + { 0x03, 0x22, 0xe0 }, /* SIMG: Auto EQ */ 205 + { 0x03, 0x23, 0xc0 }, /* SIMG: Auto EQ */ 206 + { 0x03, 0x24, 0xa0 }, /* SIMG: Auto EQ */ 207 + { 0x03, 0x25, 0x80 }, /* SIMG: Auto EQ */ 208 + { 0x03, 0x26, 0x60 }, /* SIMG: Auto EQ */ 209 + { 0x03, 0x27, 0x40 }, /* SIMG: Auto EQ */ 210 + { 0x03, 0x28, 0x20 }, /* SIMG: Auto EQ */ 211 + { 0x03, 0x29, 0x00 }, /* SIMG: Auto EQ */ 212 + { 0x03, 0x31, 0x0b }, /* SIMG: Rx PLL BW value from I2C BW ~ 4MHz */ 213 + { 0x03, 0x45, 0x06 }, /* SIMG: DPLL Mode */ 214 + { 0x03, 0x4b, 0x06 }, /* SIMG: Correcting HW default */ 215 + { 0x03, 0x4c, 0xa0 }, /* Manual zone control */ 216 + { 0x03, 0x4d, 0x02 }, /* SIMG: PLL Mode Value (order is important) */ 217 + }; 218 + 219 + static int sii9234_set_internal(struct sii9234_context *ctx) 220 + { 221 + struct i2c_client *client = ctx->client; 222 + int i, ret; 223 + 224 + for (i = 0; i < ARRAY_SIZE(data); ++i) { 225 + int addr = (data[i][0] << 8) | data[i][1]; 226 + ret = sii9234_writeb_idx(client, addr, data[i][2]); 227 + if (ret < 0) 228 + return ret; 229 + } 230 + return 0; 231 + } 232 + 233 + static int sii9234_runtime_suspend(struct device *dev) 234 + { 235 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 236 + struct sii9234_context *ctx = sd_to_context(sd); 237 + struct i2c_client *client = ctx->client; 238 + 239 + dev_info(dev, "suspend start\n"); 240 + 241 + sii9234_writeb_mask(client, 0x1e, 3, 3); 242 + regulator_disable(ctx->power); 243 + 244 + return 0; 245 + } 246 + 247 + static int sii9234_runtime_resume(struct device *dev) 248 + { 249 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 250 + struct sii9234_context *ctx = sd_to_context(sd); 251 + struct i2c_client *client = ctx->client; 252 + int ret; 253 + 254 + dev_info(dev, "resume start\n"); 255 + regulator_enable(ctx->power); 256 + 257 + ret = sii9234_reset(ctx); 258 + if (ret) 259 + goto fail; 260 + 261 + /* enable tpi */ 262 + ret = sii9234_writeb_mask(client, 0x1e, 1, 0); 263 + if (ret < 0) 264 + goto fail; 265 + ret = sii9234_set_internal(ctx); 266 + if (ret < 0) 267 + goto fail; 268 + 269 + return 0; 270 + 271 + fail: 272 + dev_err(dev, "failed to resume\n"); 273 + regulator_disable(ctx->power); 274 + 275 + return ret; 276 + } 277 + 278 + static const struct dev_pm_ops sii9234_pm_ops = { 279 + .runtime_suspend = sii9234_runtime_suspend, 280 + .runtime_resume = sii9234_runtime_resume, 281 + }; 282 + 283 + static int sii9234_s_power(struct v4l2_subdev *sd, int on) 284 + { 285 + struct sii9234_context *ctx = sd_to_context(sd); 286 + int ret; 287 + 288 + if (on) 289 + ret = pm_runtime_get_sync(&ctx->client->dev); 290 + else 291 + ret = pm_runtime_put(&ctx->client->dev); 292 + /* only values < 0 indicate errors */ 293 + return IS_ERR_VALUE(ret) ? ret : 0; 294 + } 295 + 296 + static int sii9234_s_stream(struct v4l2_subdev *sd, int enable) 297 + { 298 + struct sii9234_context *ctx = sd_to_context(sd); 299 + 300 + /* (dis/en)able TDMS output */ 301 + sii9234_writeb_mask(ctx->client, 0x1a, enable ? 0 : ~0 , 1 << 4); 302 + return 0; 303 + } 304 + 305 + static const struct v4l2_subdev_core_ops sii9234_core_ops = { 306 + .s_power = sii9234_s_power, 307 + }; 308 + 309 + static const struct v4l2_subdev_video_ops sii9234_video_ops = { 310 + .s_stream = sii9234_s_stream, 311 + }; 312 + 313 + static const struct v4l2_subdev_ops sii9234_ops = { 314 + .core = &sii9234_core_ops, 315 + .video = &sii9234_video_ops, 316 + }; 317 + 318 + static int __devinit sii9234_probe(struct i2c_client *client, 319 + const struct i2c_device_id *id) 320 + { 321 + struct device *dev = &client->dev; 322 + struct sii9234_platform_data *pdata = dev->platform_data; 323 + struct sii9234_context *ctx; 324 + int ret; 325 + 326 + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 327 + if (!ctx) { 328 + dev_err(dev, "out of memory\n"); 329 + ret = -ENOMEM; 330 + goto fail; 331 + } 332 + ctx->client = client; 333 + 334 + ctx->power = regulator_get(dev, "hdmi-en"); 335 + if (IS_ERR(ctx->power)) { 336 + dev_err(dev, "failed to acquire regulator hdmi-en\n"); 337 + ret = PTR_ERR(ctx->power); 338 + goto fail_ctx; 339 + } 340 + 341 + ctx->gpio_n_reset = pdata->gpio_n_reset; 342 + ret = gpio_request(ctx->gpio_n_reset, "MHL_RST"); 343 + if (ret) { 344 + dev_err(dev, "failed to acquire MHL_RST gpio\n"); 345 + goto fail_power; 346 + } 347 + 348 + v4l2_i2c_subdev_init(&ctx->sd, client, &sii9234_ops); 349 + 350 + pm_runtime_enable(dev); 351 + 352 + /* enable device */ 353 + ret = pm_runtime_get_sync(dev); 354 + if (ret) 355 + goto fail_pm; 356 + 357 + /* verify chip version */ 358 + ret = sii9234_verify_version(client); 359 + if (ret) 360 + goto fail_pm_get; 361 + 362 + /* stop processing */ 363 + pm_runtime_put(dev); 364 + 365 + dev_info(dev, "probe successful\n"); 366 + 367 + return 0; 368 + 369 + fail_pm_get: 370 + pm_runtime_put_sync(dev); 371 + 372 + fail_pm: 373 + pm_runtime_disable(dev); 374 + gpio_free(ctx->gpio_n_reset); 375 + 376 + fail_power: 377 + regulator_put(ctx->power); 378 + 379 + fail_ctx: 380 + kfree(ctx); 381 + 382 + fail: 383 + dev_err(dev, "probe failed\n"); 384 + 385 + return ret; 386 + } 387 + 388 + static int __devexit sii9234_remove(struct i2c_client *client) 389 + { 390 + struct device *dev = &client->dev; 391 + struct v4l2_subdev *sd = i2c_get_clientdata(client); 392 + struct sii9234_context *ctx = sd_to_context(sd); 393 + 394 + pm_runtime_disable(dev); 395 + gpio_free(ctx->gpio_n_reset); 396 + regulator_put(ctx->power); 397 + kfree(ctx); 398 + 399 + dev_info(dev, "remove successful\n"); 400 + 401 + return 0; 402 + } 403 + 404 + 405 + static const struct i2c_device_id sii9234_id[] = { 406 + { "SII9234", 0 }, 407 + { }, 408 + }; 409 + 410 + MODULE_DEVICE_TABLE(i2c, sii9234_id); 411 + static struct i2c_driver sii9234_driver = { 412 + .driver = { 413 + .name = "sii9234", 414 + .owner = THIS_MODULE, 415 + .pm = &sii9234_pm_ops, 416 + }, 417 + .probe = sii9234_probe, 418 + .remove = __devexit_p(sii9234_remove), 419 + .id_table = sii9234_id, 420 + }; 421 + 422 + static int __init sii9234_init(void) 423 + { 424 + return i2c_add_driver(&sii9234_driver); 425 + } 426 + module_init(sii9234_init); 427 + 428 + static void __exit sii9234_exit(void) 429 + { 430 + i2c_del_driver(&sii9234_driver); 431 + } 432 + module_exit(sii9234_exit);
+1 -12
drivers/media/video/saa6588.c
··· 539 539 .id_table = saa6588_id, 540 540 }; 541 541 542 - static __init int init_saa6588(void) 543 - { 544 - return i2c_add_driver(&saa6588_driver); 545 - } 546 - 547 - static __exit void exit_saa6588(void) 548 - { 549 - i2c_del_driver(&saa6588_driver); 550 - } 551 - 552 - module_init(init_saa6588); 553 - module_exit(exit_saa6588); 542 + module_i2c_driver(saa6588_driver);
+1 -12
drivers/media/video/saa7110.c
··· 491 491 .id_table = saa7110_id, 492 492 }; 493 493 494 - static __init int init_saa7110(void) 495 - { 496 - return i2c_add_driver(&saa7110_driver); 497 - } 498 - 499 - static __exit void exit_saa7110(void) 500 - { 501 - i2c_del_driver(&saa7110_driver); 502 - } 503 - 504 - module_init(init_saa7110); 505 - module_exit(exit_saa7110); 494 + module_i2c_driver(saa7110_driver);
+1 -12
drivers/media/video/saa7115.c
··· 1724 1724 .id_table = saa711x_id, 1725 1725 }; 1726 1726 1727 - static __init int init_saa711x(void) 1728 - { 1729 - return i2c_add_driver(&saa711x_driver); 1730 - } 1731 - 1732 - static __exit void exit_saa711x(void) 1733 - { 1734 - i2c_del_driver(&saa711x_driver); 1735 - } 1736 - 1737 - module_init(init_saa711x); 1738 - module_exit(exit_saa711x); 1727 + module_i2c_driver(saa711x_driver);
+1 -12
drivers/media/video/saa7127.c
··· 852 852 .id_table = saa7127_id, 853 853 }; 854 854 855 - static __init int init_saa7127(void) 856 - { 857 - return i2c_add_driver(&saa7127_driver); 858 - } 859 - 860 - static __exit void exit_saa7127(void) 861 - { 862 - i2c_del_driver(&saa7127_driver); 863 - } 864 - 865 - module_init(init_saa7127); 866 - module_exit(exit_saa7127); 855 + module_i2c_driver(saa7127_driver);
+4 -4
drivers/media/video/saa7134/Makefile
··· 10 10 11 11 obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o 12 12 13 - ccflags-y += -Idrivers/media/video 14 - ccflags-y += -Idrivers/media/common/tuners 15 - ccflags-y += -Idrivers/media/dvb/dvb-core 16 - ccflags-y += -Idrivers/media/dvb/frontends 13 + ccflags-y += -I$(srctree)/drivers/media/video 14 + ccflags-y += -I$(srctree)/drivers/media/common/tuners 15 + ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core 16 + ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
+1 -12
drivers/media/video/saa7134/saa6752hs.c
··· 1001 1001 .id_table = saa6752hs_id, 1002 1002 }; 1003 1003 1004 - static __init int init_saa6752hs(void) 1005 - { 1006 - return i2c_add_driver(&saa6752hs_driver); 1007 - } 1008 - 1009 - static __exit void exit_saa6752hs(void) 1010 - { 1011 - i2c_del_driver(&saa6752hs_driver); 1012 - } 1013 - 1014 - module_init(init_saa6752hs); 1015 - module_exit(exit_saa6752hs); 1004 + module_i2c_driver(saa6752hs_driver); 1016 1005 1017 1006 /* 1018 1007 * Overrides for Emacs so that we follow Linus's tabbing style.
+59
drivers/media/video/saa7134/saa7134-cards.c
··· 33 33 #include "tea5767.h" 34 34 #include "tda18271.h" 35 35 #include "xc5000.h" 36 + #include "s5h1411.h" 36 37 37 38 /* commly used strings */ 38 39 static char name_mute[] = "mute"; ··· 5713 5712 .amux = LINE1, 5714 5713 } }, 5715 5714 }, 5715 + [SAA7134_BOARD_KWORLD_PC150U] = { 5716 + .name = "Kworld PC150-U", 5717 + .audio_clock = 0x00187de7, 5718 + .tuner_type = TUNER_PHILIPS_TDA8290, 5719 + .radio_type = UNSET, 5720 + .tuner_addr = ADDR_UNSET, 5721 + .radio_addr = ADDR_UNSET, 5722 + .mpeg = SAA7134_MPEG_DVB, 5723 + .gpiomask = 1 << 21, 5724 + .ts_type = SAA7134_MPEG_TS_PARALLEL, 5725 + .inputs = { { 5726 + .name = name_tv, 5727 + .vmux = 1, 5728 + .amux = TV, 5729 + .tv = 1, 5730 + }, { 5731 + .name = name_comp, 5732 + .vmux = 3, 5733 + .amux = LINE1, 5734 + }, { 5735 + .name = name_svideo, 5736 + .vmux = 8, 5737 + .amux = LINE2, 5738 + } }, 5739 + .radio = { 5740 + .name = name_radio, 5741 + .amux = TV, 5742 + .gpio = 0x0000000, 5743 + }, 5744 + }, 5716 5745 5717 5746 }; 5718 5747 ··· 6336 6305 .subdevice = 0x7352, 6337 6306 .driver_data = SAA7134_BOARD_KWORLD_ATSC110, /* ATSC 115 */ 6338 6307 },{ 6308 + .vendor = PCI_VENDOR_ID_PHILIPS, 6309 + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */ 6310 + .subvendor = 0x17de, 6311 + .subdevice = 0xa134, 6312 + .driver_data = SAA7134_BOARD_KWORLD_PC150U, 6313 + }, { 6339 6314 .vendor = PCI_VENDOR_ID_PHILIPS, 6340 6315 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6341 6316 .subvendor = 0x1461, ··· 7171 7134 return 0; 7172 7135 } 7173 7136 7137 + static int saa7134_kworld_pc150u_toggle_agc(struct saa7134_dev *dev, 7138 + enum tda18271_mode mode) 7139 + { 7140 + switch (mode) { 7141 + case TDA18271_ANALOG: 7142 + saa7134_set_gpio(dev, 18, 0); 7143 + break; 7144 + case TDA18271_DIGITAL: 7145 + saa7134_set_gpio(dev, 18, 1); 7146 + msleep(30); 7147 + break; 7148 + default: 7149 + return -EINVAL; 7150 + } 7151 + return 0; 7152 + } 7153 + 7174 7154 static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev, 7175 7155 int command, int arg) 7176 7156 { ··· 7203 7149 break; 7204 7150 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7205 7151 ret = saa7134_kworld_sbtvd_toggle_agc(dev, arg); 7152 + break; 7153 + case SAA7134_BOARD_KWORLD_PC150U: 7154 + ret = saa7134_kworld_pc150u_toggle_agc(dev, arg); 7206 7155 break; 7207 7156 default: 7208 7157 break; ··· 7228 7171 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 7229 7172 case SAA7134_BOARD_AVERMEDIA_M733A: 7230 7173 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7174 + case SAA7134_BOARD_KWORLD_PC150U: 7231 7175 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2: 7232 7176 /* tda8290 + tda18271 */ 7233 7177 ret = saa7134_tda8290_18271_callback(dev, command, arg); ··· 7510 7452 case SAA7134_BOARD_BEHOLD_X7: 7511 7453 case SAA7134_BOARD_BEHOLD_H7: 7512 7454 case SAA7134_BOARD_BEHOLD_A7: 7455 + case SAA7134_BOARD_KWORLD_PC150U: 7513 7456 dev->has_remote = SAA7134_REMOTE_I2C; 7514 7457 break; 7515 7458 case SAA7134_BOARD_AVERMEDIA_A169_B:
+44
drivers/media/video/saa7134/saa7134-dvb.c
··· 61 61 #include "zl10036.h" 62 62 #include "zl10039.h" 63 63 #include "mt312.h" 64 + #include "s5h1411.h" 64 65 65 66 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 66 67 MODULE_LICENSE("GPL"); ··· 1159 1158 .output_opt = TDA18271_OUTPUT_LT_OFF, 1160 1159 }; 1161 1160 1161 + static struct tda18271_std_map kworld_tda18271_std_map = { 1162 + .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3, 1163 + .if_lvl = 6, .rfagc_top = 0x37 }, 1164 + .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, 1165 + .if_lvl = 6, .rfagc_top = 0x37 }, 1166 + }; 1167 + 1168 + static struct tda18271_config kworld_pc150u_tda18271_config = { 1169 + .std_map = &kworld_tda18271_std_map, 1170 + .gate = TDA18271_GATE_ANALOG, 1171 + .output_opt = TDA18271_OUTPUT_LT_OFF, 1172 + .config = 3, /* Use tuner callback for AGC */ 1173 + .rf_cal_on_startup = 1 1174 + }; 1175 + 1176 + static struct s5h1411_config kworld_s5h1411_config = { 1177 + .output_mode = S5H1411_PARALLEL_OUTPUT, 1178 + .gpio = S5H1411_GPIO_OFF, 1179 + .qam_if = S5H1411_IF_4000, 1180 + .vsb_if = S5H1411_IF_3250, 1181 + .inversion = S5H1411_INVERSION_ON, 1182 + .status_mode = S5H1411_DEMODLOCKING, 1183 + .mpeg_timing = 1184 + S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, 1185 + }; 1186 + 1187 + 1162 1188 /* ================================================================== 1163 1189 * Core code 1164 1190 */ ··· 1465 1437 dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1466 1438 &dev->i2c_adap, 0x61, 1467 1439 TUNER_PHILIPS_TUV1236D); 1440 + break; 1441 + case SAA7134_BOARD_KWORLD_PC150U: 1442 + saa7134_set_gpio(dev, 18, 1); /* Switch to digital mode */ 1443 + saa7134_tuner_callback(dev, 0, 1444 + TDA18271_CALLBACK_CMD_AGC_ENABLE, 1); 1445 + fe0->dvb.frontend = dvb_attach(s5h1411_attach, 1446 + &kworld_s5h1411_config, 1447 + &dev->i2c_adap); 1448 + if (fe0->dvb.frontend != NULL) { 1449 + dvb_attach(tda829x_attach, fe0->dvb.frontend, 1450 + &dev->i2c_adap, 0x4b, 1451 + &tda829x_no_probe); 1452 + dvb_attach(tda18271_attach, fe0->dvb.frontend, 1453 + 0x60, &dev->i2c_adap, 1454 + &kworld_pc150u_tda18271_config); 1455 + } 1468 1456 break; 1469 1457 case SAA7134_BOARD_FLYDVBS_LR300: 1470 1458 fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+13 -1
drivers/media/video/saa7134/saa7134-i2c.c
··· 254 254 addr = msgs[i].addr << 1; 255 255 if (msgs[i].flags & I2C_M_RD) 256 256 addr |= 1; 257 - if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) { 257 + if (i > 0 && msgs[i].flags & 258 + I2C_M_RD && msgs[i].addr != 0x40 && 259 + msgs[i].addr != 0x19) { 258 260 /* workaround for a saa7134 i2c bug 259 261 * needed to talk to the mt352 demux 260 262 * thanks to pinnacle for the hint */ ··· 280 278 goto err; 281 279 d1printk("%02x", rc); 282 280 msgs[i].buf[byte] = rc; 281 + } 282 + /* discard mysterious extra byte when reading 283 + from Samsung S5H1411. i2c bus gets error 284 + if we do not. */ 285 + if (0x19 == msgs[i].addr) { 286 + d1printk(" ?"); 287 + rc = i2c_recv_byte(dev); 288 + if (rc < 0) 289 + goto err; 290 + d1printk("%02x", rc); 283 291 } 284 292 } else { 285 293 /* write bytes */
+63
drivers/media/video/saa7134/saa7134-input.c
··· 210 210 return 1; 211 211 } 212 212 213 + /* copied and modified from get_key_msi_tvanywhere_plus() */ 214 + static int get_key_kworld_pc150u(struct IR_i2c *ir, u32 *ir_key, 215 + u32 *ir_raw) 216 + { 217 + unsigned char b; 218 + unsigned int gpio; 219 + 220 + /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ 221 + struct saa7134_dev *dev = ir->c->adapter->algo_data; 222 + if (dev == NULL) { 223 + i2cdprintk("get_key_kworld_pc150u: " 224 + "ir->c->adapter->algo_data is NULL!\n"); 225 + return -EIO; 226 + } 227 + 228 + /* rising SAA7134_GPIO_GPRESCAN reads the status */ 229 + 230 + saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 231 + saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); 232 + 233 + gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); 234 + 235 + /* GPIO&0x100 is pulsed low when a button is pressed. Don't do 236 + I2C receive if gpio&0x100 is not low. */ 237 + 238 + if (gpio & 0x100) 239 + return 0; /* No button press */ 240 + 241 + /* GPIO says there is a button press. Get it. */ 242 + 243 + if (1 != i2c_master_recv(ir->c, &b, 1)) { 244 + i2cdprintk("read error\n"); 245 + return -EIO; 246 + } 247 + 248 + /* No button press */ 249 + 250 + if (b == 0xff) 251 + return 0; 252 + 253 + /* Button pressed */ 254 + 255 + dprintk("get_key_kworld_pc150u: Key = 0x%02X\n", b); 256 + *ir_key = b; 257 + *ir_raw = b; 258 + return 1; 259 + } 260 + 213 261 static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 214 262 { 215 263 unsigned char b; ··· 939 891 * otherwise it will miss some keypresses 940 892 */ 941 893 dev->init_data.polling_interval = 50; 894 + info.addr = 0x30; 895 + /* MSI TV@nywhere Plus controller doesn't seem to 896 + respond to probes unless we read something from 897 + an existing device. Weird... 898 + REVISIT: might no longer be needed */ 899 + rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1); 900 + dprintk("probe 0x%02x @ %s: %s\n", 901 + msg_msi.addr, dev->i2c_adap.name, 902 + (1 == rc) ? "yes" : "no"); 903 + break; 904 + case SAA7134_BOARD_KWORLD_PC150U: 905 + /* copied and modified from MSI TV@nywhere Plus */ 906 + dev->init_data.name = "Kworld PC150-U"; 907 + dev->init_data.get_key = get_key_kworld_pc150u; 908 + dev->init_data.ir_codes = RC_MAP_KWORLD_PC150U; 942 909 info.addr = 0x30; 943 910 /* MSI TV@nywhere Plus controller doesn't seem to 944 911 respond to probes unless we read something from
+3 -2
drivers/media/video/saa7134/saa7134.h
··· 126 126 unsigned users; 127 127 128 128 u32 polling; 129 - u32 last_gpio; 130 - u32 mask_keycode, mask_keydown, mask_keyup; 129 + u32 last_gpio; 130 + u32 mask_keycode, mask_keydown, mask_keyup; 131 131 132 132 bool running; 133 133 bool active; ··· 331 331 #define SAA7134_BOARD_BEHOLD_501 186 332 332 #define SAA7134_BOARD_BEHOLD_503FM 187 333 333 #define SAA7134_BOARD_SENSORAY811_911 188 334 + #define SAA7134_BOARD_KWORLD_PC150U 189 334 335 335 336 #define SAA7134_MAXBOARDS 32 336 337 #define SAA7134_INPUT_MAX 8
+4 -4
drivers/media/video/saa7164/Makefile
··· 4 4 5 5 obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o 6 6 7 - ccflags-y += -Idrivers/media/video 8 - ccflags-y += -Idrivers/media/common/tuners 9 - ccflags-y += -Idrivers/media/dvb/dvb-core 10 - ccflags-y += -Idrivers/media/dvb/frontends 7 + ccflags-y += -I$(srctree)/drivers/media/video 8 + ccflags-y += -I$(srctree)/drivers/media/common/tuners 9 + ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core 10 + ccflags-y += -I$(srctree)/drivers/media/dvb/frontends 11 11 12 12 ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
-6
drivers/media/video/saa7164/saa7164-encoder.c
··· 791 791 return 0; 792 792 } 793 793 794 - static int vidioc_log_status(struct file *file, void *priv) 795 - { 796 - return 0; 797 - } 798 - 799 794 static int fill_queryctrl(struct saa7164_encoder_params *params, 800 795 struct v4l2_queryctrl *c) 801 796 { ··· 1342 1347 .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, 1343 1348 .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, 1344 1349 .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, 1345 - .vidioc_log_status = vidioc_log_status, 1346 1350 .vidioc_queryctrl = vidioc_queryctrl, 1347 1351 .vidioc_g_chip_ident = saa7164_g_chip_ident, 1348 1352 #ifdef CONFIG_VIDEO_ADV_DEBUG
-6
drivers/media/video/saa7164/saa7164-vbi.c
··· 730 730 return 0; 731 731 } 732 732 733 - static int vidioc_log_status(struct file *file, void *priv) 734 - { 735 - return 0; 736 - } 737 - 738 733 static int fill_queryctrl(struct saa7164_vbi_params *params, 739 734 struct v4l2_queryctrl *c) 740 735 { ··· 1251 1256 .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, 1252 1257 .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, 1253 1258 .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, 1254 - .vidioc_log_status = vidioc_log_status, 1255 1259 .vidioc_queryctrl = vidioc_queryctrl, 1256 1260 #if 0 1257 1261 .vidioc_g_chip_ident = saa7164_g_chip_ident,
+1 -12
drivers/media/video/saa717x.c
··· 1375 1375 .id_table = saa717x_id, 1376 1376 }; 1377 1377 1378 - static __init int init_saa717x(void) 1379 - { 1380 - return i2c_add_driver(&saa717x_driver); 1381 - } 1382 - 1383 - static __exit void exit_saa717x(void) 1384 - { 1385 - i2c_del_driver(&saa717x_driver); 1386 - } 1387 - 1388 - module_init(init_saa717x); 1389 - module_exit(exit_saa717x); 1378 + module_i2c_driver(saa717x_driver);
+1 -12
drivers/media/video/saa7185.c
··· 374 374 .id_table = saa7185_id, 375 375 }; 376 376 377 - static __init int init_saa7185(void) 378 - { 379 - return i2c_add_driver(&saa7185_driver); 380 - } 381 - 382 - static __exit void exit_saa7185(void) 383 - { 384 - i2c_del_driver(&saa7185_driver); 385 - } 386 - 387 - module_init(init_saa7185); 388 - module_exit(exit_saa7185); 377 + module_i2c_driver(saa7185_driver);
+1 -12
drivers/media/video/saa7191.c
··· 656 656 .id_table = saa7191_id, 657 657 }; 658 658 659 - static __init int init_saa7191(void) 660 - { 661 - return i2c_add_driver(&saa7191_driver); 662 - } 663 - 664 - static __exit void exit_saa7191(void) 665 - { 666 - i2c_del_driver(&saa7191_driver); 667 - } 668 - 669 - module_init(init_saa7191); 670 - module_exit(exit_saa7191); 659 + module_i2c_driver(saa7191_driver);
+27 -8
drivers/media/video/sh_mobile_ceu_camera.c
··· 112 112 113 113 u32 cflcr; 114 114 115 + /* static max sizes either from platform data or default */ 116 + int max_width; 117 + int max_height; 118 + 115 119 enum v4l2_field field; 116 120 int sequence; 117 121 ··· 1085 1081 if (ret < 0) 1086 1082 return ret; 1087 1083 1088 - while ((mf.width > 2560 || mf.height > 1920) && shift < 4) { 1084 + /* 1085 + * All currently existing CEU implementations support 2560x1920 1086 + * or larger frames. If the sensor is proposing too big a frame, 1087 + * don't bother with possibly supportred by the CEU larger 1088 + * sizes, just try VGA multiples. If needed, this can be 1089 + * adjusted in the future. 1090 + */ 1091 + while ((mf.width > pcdev->max_width || 1092 + mf.height > pcdev->max_height) && shift < 4) { 1089 1093 /* Try 2560x1920, 1280x960, 640x480, 320x240 */ 1090 1094 mf.width = 2560 >> shift; 1091 1095 mf.height = 1920 >> shift; ··· 1389 1377 static int client_s_fmt(struct soc_camera_device *icd, 1390 1378 struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) 1391 1379 { 1380 + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1381 + struct sh_mobile_ceu_dev *pcdev = ici->priv; 1392 1382 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1393 1383 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1394 1384 struct device *dev = icd->parent; ··· 1424 1410 if (ret < 0) 1425 1411 return ret; 1426 1412 1427 - max_width = min(cap.bounds.width, 2560); 1428 - max_height = min(cap.bounds.height, 1920); 1413 + max_width = min(cap.bounds.width, pcdev->max_width); 1414 + max_height = min(cap.bounds.height, pcdev->max_height); 1429 1415 1430 1416 /* Camera set a format, but geometry is not precise, try to improve */ 1431 1417 tmp_w = mf->width; ··· 1565 1551 if (ret < 0) 1566 1552 return ret; 1567 1553 1568 - if (mf.width > 2560 || mf.height > 1920) 1554 + if (mf.width > pcdev->max_width || mf.height > pcdev->max_height) 1569 1555 return -EINVAL; 1570 1556 1571 1557 /* 4. Calculate camera scales */ ··· 1848 1834 static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, 1849 1835 struct v4l2_format *f) 1850 1836 { 1837 + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1838 + struct sh_mobile_ceu_dev *pcdev = ici->priv; 1851 1839 const struct soc_camera_format_xlate *xlate; 1852 1840 struct v4l2_pix_format *pix = &f->fmt.pix; 1853 1841 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); ··· 1870 1854 /* FIXME: calculate using depth and bus width */ 1871 1855 1872 1856 /* CFSZR requires height and width to be 4-pixel aligned */ 1873 - v4l_bound_align_image(&pix->width, 2, 2560, 2, 1874 - &pix->height, 4, 1920, 2, 0); 1857 + v4l_bound_align_image(&pix->width, 2, pcdev->max_width, 2, 1858 + &pix->height, 4, pcdev->max_height, 2, 0); 1875 1859 1876 1860 width = pix->width; 1877 1861 height = pix->height; ··· 1906 1890 * requested a bigger rectangle, it will not return a 1907 1891 * smaller one. 1908 1892 */ 1909 - mf.width = 2560; 1910 - mf.height = 1920; 1893 + mf.width = pcdev->max_width; 1894 + mf.height = pcdev->max_height; 1911 1895 ret = v4l2_device_call_until_err(sd->v4l2_dev, 1912 1896 soc_camera_grp_id(icd), video, 1913 1897 try_mbus_fmt, &mf); ··· 2097 2081 dev_err(&pdev->dev, "CEU platform data not set.\n"); 2098 2082 goto exit_kfree; 2099 2083 } 2084 + 2085 + pcdev->max_width = pcdev->pdata->max_width ? : 2560; 2086 + pcdev->max_height = pcdev->pdata->max_height ? : 1920; 2100 2087 2101 2088 base = ioremap_nocache(res->start, resource_size(res)); 2102 2089 if (!base) {
+16 -16
drivers/media/video/soc_camera.c
··· 526 526 }, 527 527 }; 528 528 529 - ret = soc_camera_power_on(icd, icl); 530 - if (ret < 0) 531 - goto epower; 532 - 533 529 /* The camera could have been already on, try to reset */ 534 530 if (icl->reset) 535 531 icl->reset(icd->pdev); ··· 535 539 dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret); 536 540 goto eiciadd; 537 541 } 542 + 543 + ret = soc_camera_power_on(icd, icl); 544 + if (ret < 0) 545 + goto epower; 538 546 539 547 pm_runtime_enable(&icd->vdev->dev); 540 548 ret = pm_runtime_resume(&icd->vdev->dev); ··· 578 578 esfmt: 579 579 pm_runtime_disable(&icd->vdev->dev); 580 580 eresume: 581 - ici->ops->remove(icd); 582 - eiciadd: 583 581 soc_camera_power_off(icd, icl); 584 582 epower: 583 + ici->ops->remove(icd); 584 + eiciadd: 585 585 icd->use_count--; 586 586 module_put(ici->ops->owner); 587 587 ··· 1050 1050 if (ret < 0) 1051 1051 goto ereg; 1052 1052 1053 + /* The camera could have been already on, try to reset */ 1054 + if (icl->reset) 1055 + icl->reset(icd->pdev); 1056 + 1057 + ret = ici->ops->add(icd); 1058 + if (ret < 0) 1059 + goto eadd; 1060 + 1053 1061 /* 1054 1062 * This will not yet call v4l2_subdev_core_ops::s_power(1), because the 1055 1063 * subdevice has not been initialised yet. We'll have to call it once ··· 1067 1059 ret = soc_camera_power_on(icd, icl); 1068 1060 if (ret < 0) 1069 1061 goto epower; 1070 - 1071 - /* The camera could have been already on, try to reset */ 1072 - if (icl->reset) 1073 - icl->reset(icd->pdev); 1074 - 1075 - ret = ici->ops->add(icd); 1076 - if (ret < 0) 1077 - goto eadd; 1078 1062 1079 1063 /* Must have icd->vdev before registering the device */ 1080 1064 ret = video_dev_create(icd); ··· 1165 1165 video_device_release(icd->vdev); 1166 1166 icd->vdev = NULL; 1167 1167 evdc: 1168 - ici->ops->remove(icd); 1169 - eadd: 1170 1168 soc_camera_power_off(icd, icl); 1171 1169 epower: 1170 + ici->ops->remove(icd); 1171 + eadd: 1172 1172 regulator_bulk_free(icl->num_regulators, icl->regulators); 1173 1173 ereg: 1174 1174 v4l2_ctrl_handler_free(&icd->ctrl_handler);
+1 -12
drivers/media/video/sr030pc30.c
··· 864 864 .id_table = sr030pc30_id, 865 865 }; 866 866 867 - static int __init sr030pc30_init(void) 868 - { 869 - return i2c_add_driver(&sr030pc30_i2c_driver); 870 - } 871 - 872 - static void __exit sr030pc30_exit(void) 873 - { 874 - i2c_del_driver(&sr030pc30_i2c_driver); 875 - } 876 - 877 - module_init(sr030pc30_init); 878 - module_exit(sr030pc30_exit); 867 + module_i2c_driver(sr030pc30_i2c_driver); 879 868 880 869 MODULE_DESCRIPTION("Siliconfile SR030PC30 camera driver"); 881 870 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+1 -12
drivers/media/video/tda7432.c
··· 482 482 .id_table = tda7432_id, 483 483 }; 484 484 485 - static __init int init_tda7432(void) 486 - { 487 - return i2c_add_driver(&tda7432_driver); 488 - } 489 - 490 - static __exit void exit_tda7432(void) 491 - { 492 - i2c_del_driver(&tda7432_driver); 493 - } 494 - 495 - module_init(init_tda7432); 496 - module_exit(exit_tda7432); 485 + module_i2c_driver(tda7432_driver);
+1 -12
drivers/media/video/tda9840.c
··· 208 208 .id_table = tda9840_id, 209 209 }; 210 210 211 - static __init int init_tda9840(void) 212 - { 213 - return i2c_add_driver(&tda9840_driver); 214 - } 215 - 216 - static __exit void exit_tda9840(void) 217 - { 218 - i2c_del_driver(&tda9840_driver); 219 - } 220 - 221 - module_init(init_tda9840); 222 - module_exit(exit_tda9840); 211 + module_i2c_driver(tda9840_driver);
+1 -12
drivers/media/video/tea6415c.c
··· 184 184 .id_table = tea6415c_id, 185 185 }; 186 186 187 - static __init int init_tea6415c(void) 188 - { 189 - return i2c_add_driver(&tea6415c_driver); 190 - } 191 - 192 - static __exit void exit_tea6415c(void) 193 - { 194 - i2c_del_driver(&tea6415c_driver); 195 - } 196 - 197 - module_init(init_tea6415c); 198 - module_exit(exit_tea6415c); 187 + module_i2c_driver(tea6415c_driver);
+1 -12
drivers/media/video/tea6420.c
··· 166 166 .id_table = tea6420_id, 167 167 }; 168 168 169 - static __init int init_tea6420(void) 170 - { 171 - return i2c_add_driver(&tea6420_driver); 172 - } 173 - 174 - static __exit void exit_tea6420(void) 175 - { 176 - i2c_del_driver(&tea6420_driver); 177 - } 178 - 179 - module_init(init_tea6420); 180 - module_exit(exit_tea6420); 169 + module_i2c_driver(tea6420_driver);
+1 -13
drivers/media/video/ths7303.c
··· 137 137 .id_table = ths7303_id, 138 138 }; 139 139 140 - static int __init ths7303_init(void) 141 - { 142 - return i2c_add_driver(&ths7303_driver); 143 - } 144 - 145 - static void __exit ths7303_exit(void) 146 - { 147 - i2c_del_driver(&ths7303_driver); 148 - } 149 - 150 - module_init(ths7303_init); 151 - module_exit(ths7303_exit); 152 - 140 + module_i2c_driver(ths7303_driver);
+1 -12
drivers/media/video/tlv320aic23b.c
··· 227 227 .id_table = tlv320aic23b_id, 228 228 }; 229 229 230 - static __init int init_tlv320aic23b(void) 231 - { 232 - return i2c_add_driver(&tlv320aic23b_driver); 233 - } 234 - 235 - static __exit void exit_tlv320aic23b(void) 236 - { 237 - i2c_del_driver(&tlv320aic23b_driver); 238 - } 239 - 240 - module_init(init_tlv320aic23b); 241 - module_exit(exit_tlv320aic23b); 230 + module_i2c_driver(tlv320aic23b_driver);
+1 -2
drivers/media/video/tm6000/tm6000-input.c
··· 481 481 482 482 dprintk(2, "%s\n",__func__); 483 483 484 - rc_unregister_device(ir->rc); 485 - 486 484 if (!ir->polling) 487 485 __tm6000_ir_int_stop(ir->rc); 488 486 ··· 490 492 tm6000_flash_led(dev, 0); 491 493 ir->pwled = 0; 492 494 495 + rc_unregister_device(ir->rc); 493 496 494 497 kfree(ir); 495 498 dev->ir = NULL;
+16 -12
drivers/media/video/tuner-core.c
··· 380 380 tune_now = 0; 381 381 break; 382 382 } 383 + case TUNER_XC5000C: 384 + { 385 + struct xc5000_config xc5000c_cfg = { 386 + .i2c_address = t->i2c->addr, 387 + /* if_khz will be set at dvb_attach() */ 388 + .if_khz = 0, 389 + .chip_id = XC5000C, 390 + }; 391 + 392 + if (!dvb_attach(xc5000_attach, 393 + &t->fe, t->i2c->adapter, &xc5000c_cfg)) 394 + goto attach_failed; 395 + tune_now = 0; 396 + break; 397 + } 383 398 case TUNER_NXP_TDA18271: 384 399 { 385 400 struct tda18271_config cfg = { ··· 1329 1314 .id_table = tuner_id, 1330 1315 }; 1331 1316 1332 - static __init int init_tuner(void) 1333 - { 1334 - return i2c_add_driver(&tuner_driver); 1335 - } 1336 - 1337 - static __exit void exit_tuner(void) 1338 - { 1339 - i2c_del_driver(&tuner_driver); 1340 - } 1341 - 1342 - module_init(init_tuner); 1343 - module_exit(exit_tuner); 1317 + module_i2c_driver(tuner_driver); 1344 1318 1345 1319 MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners"); 1346 1320 MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
+1 -12
drivers/media/video/tvaudio.c
··· 2078 2078 .id_table = tvaudio_id, 2079 2079 }; 2080 2080 2081 - static __init int init_tvaudio(void) 2082 - { 2083 - return i2c_add_driver(&tvaudio_driver); 2084 - } 2085 - 2086 - static __exit void exit_tvaudio(void) 2087 - { 2088 - i2c_del_driver(&tvaudio_driver); 2089 - } 2090 - 2091 - module_init(init_tvaudio); 2092 - module_exit(exit_tvaudio); 2081 + module_i2c_driver(tvaudio_driver);
+9 -1
drivers/media/video/tveeprom.c
··· 286 286 { TUNER_ABSENT, "MaxLinear 301"}, 287 287 { TUNER_ABSENT, "Mirics MSi001"}, 288 288 { TUNER_ABSENT, "MaxLinear MxL241SF"}, 289 - { TUNER_ABSENT, "Xceive XC5000C"}, 289 + { TUNER_XC5000C, "Xceive XC5000C"}, 290 290 { TUNER_ABSENT, "Montage M68TS2020"}, 291 + { TUNER_ABSENT, "Siano SMS1530"}, 292 + { TUNER_ABSENT, "Dibcom 7090"}, 293 + { TUNER_ABSENT, "Xceive XC5200C"}, 294 + { TUNER_ABSENT, "NXP 18273"}, 295 + { TUNER_ABSENT, "Montage M88TS2022"}, 296 + /* 180-189 */ 297 + { TUNER_ABSENT, "NXP 18272M"}, 298 + { TUNER_ABSENT, "NXP 18272S"}, 291 299 }; 292 300 293 301 /* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
+1 -12
drivers/media/video/tvp514x.c
··· 1163 1163 .id_table = tvp514x_id, 1164 1164 }; 1165 1165 1166 - static int __init tvp514x_init(void) 1167 - { 1168 - return i2c_add_driver(&tvp514x_driver); 1169 - } 1170 - 1171 - static void __exit tvp514x_exit(void) 1172 - { 1173 - i2c_del_driver(&tvp514x_driver); 1174 - } 1175 - 1176 - module_init(tvp514x_init); 1177 - module_exit(tvp514x_exit); 1166 + module_i2c_driver(tvp514x_driver);
+124 -17
drivers/media/video/tvp5150.c
··· 17 17 18 18 #include "tvp5150_reg.h" 19 19 20 + #define TVP5150_H_MAX 720 21 + #define TVP5150_V_MAX_525_60 480 22 + #define TVP5150_V_MAX_OTHERS 576 23 + #define TVP5150_MAX_CROP_LEFT 511 24 + #define TVP5150_MAX_CROP_TOP 127 25 + #define TVP5150_CROP_SHIFT 2 26 + 20 27 MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); 21 28 MODULE_AUTHOR("Mauro Carvalho Chehab"); 22 29 MODULE_LICENSE("GPL"); ··· 36 29 struct tvp5150 { 37 30 struct v4l2_subdev sd; 38 31 struct v4l2_ctrl_handler hdl; 32 + struct v4l2_rect rect; 39 33 40 34 v4l2_std_id norm; /* Current set standard */ 41 35 u32 input; ··· 740 732 if (decoder->norm == std) 741 733 return 0; 742 734 735 + /* Change cropping height limits */ 736 + if (std & V4L2_STD_525_60) 737 + decoder->rect.height = TVP5150_V_MAX_525_60; 738 + else 739 + decoder->rect.height = TVP5150_V_MAX_OTHERS; 740 + 741 + 743 742 return tvp5150_set_std(sd, std); 744 743 } 745 744 ··· 843 828 else 844 829 std = decoder->norm; 845 830 846 - f->width = 720; 847 - if (std & V4L2_STD_525_60) 848 - f->height = 480; 849 - else 850 - f->height = 576; 831 + f->width = decoder->rect.width; 832 + f->height = decoder->rect.height; 851 833 852 834 f->code = V4L2_MBUS_FMT_YUYV8_2X8; 853 835 f->field = V4L2_FIELD_SEQ_TB; ··· 852 840 853 841 v4l2_dbg(1, debug, sd, "width = %d, height = %d\n", f->width, 854 842 f->height); 843 + return 0; 844 + } 845 + 846 + static int tvp5150_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 847 + { 848 + struct v4l2_rect rect = a->c; 849 + struct tvp5150 *decoder = to_tvp5150(sd); 850 + v4l2_std_id std; 851 + int hmax; 852 + 853 + v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n", 854 + __func__, rect.left, rect.top, rect.width, rect.height); 855 + 856 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 857 + return -EINVAL; 858 + 859 + /* tvp5150 has some special limits */ 860 + rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT); 861 + rect.width = clamp(rect.width, 862 + TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left, 863 + TVP5150_H_MAX - rect.left); 864 + rect.top = clamp(rect.top, 0, TVP5150_MAX_CROP_TOP); 865 + 866 + /* Calculate height based on current standard */ 867 + if (decoder->norm == V4L2_STD_ALL) 868 + std = tvp5150_read_std(sd); 869 + else 870 + std = decoder->norm; 871 + 872 + if (std & V4L2_STD_525_60) 873 + hmax = TVP5150_V_MAX_525_60; 874 + else 875 + hmax = TVP5150_V_MAX_OTHERS; 876 + 877 + rect.height = clamp(rect.height, 878 + hmax - TVP5150_MAX_CROP_TOP - rect.top, 879 + hmax - rect.top); 880 + 881 + tvp5150_write(sd, TVP5150_VERT_BLANKING_START, rect.top); 882 + tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 883 + rect.top + rect.height - hmax); 884 + tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_MSB, 885 + rect.left >> TVP5150_CROP_SHIFT); 886 + tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_LSB, 887 + rect.left | (1 << TVP5150_CROP_SHIFT)); 888 + tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_MSB, 889 + (rect.left + rect.width - TVP5150_MAX_CROP_LEFT) >> 890 + TVP5150_CROP_SHIFT); 891 + tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_LSB, 892 + rect.left + rect.width - TVP5150_MAX_CROP_LEFT); 893 + 894 + decoder->rect = rect; 895 + 896 + return 0; 897 + } 898 + 899 + static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 900 + { 901 + struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd); 902 + 903 + a->c = decoder->rect; 904 + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 905 + 906 + return 0; 907 + } 908 + 909 + static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 910 + { 911 + struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd); 912 + v4l2_std_id std; 913 + 914 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 915 + return -EINVAL; 916 + 917 + a->bounds.left = 0; 918 + a->bounds.top = 0; 919 + a->bounds.width = TVP5150_H_MAX; 920 + 921 + /* Calculate height based on current standard */ 922 + if (decoder->norm == V4L2_STD_ALL) 923 + std = tvp5150_read_std(sd); 924 + else 925 + std = decoder->norm; 926 + 927 + if (std & V4L2_STD_525_60) 928 + a->bounds.height = TVP5150_V_MAX_525_60; 929 + else 930 + a->bounds.height = TVP5150_V_MAX_OTHERS; 931 + 932 + a->defrect = a->bounds; 933 + a->pixelaspect.numerator = 1; 934 + a->pixelaspect.denominator = 1; 935 + 855 936 return 0; 856 937 } 857 938 ··· 1103 998 .enum_mbus_fmt = tvp5150_enum_mbus_fmt, 1104 999 .s_mbus_fmt = tvp5150_mbus_fmt, 1105 1000 .try_mbus_fmt = tvp5150_mbus_fmt, 1001 + .g_mbus_fmt = tvp5150_mbus_fmt, 1002 + .s_crop = tvp5150_s_crop, 1003 + .g_crop = tvp5150_g_crop, 1004 + .cropcap = tvp5150_cropcap, 1106 1005 }; 1107 1006 1108 1007 static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { ··· 1192 1083 } 1193 1084 v4l2_ctrl_handler_setup(&core->hdl); 1194 1085 1086 + /* Default is no cropping */ 1087 + core->rect.top = 0; 1088 + if (tvp5150_read_std(sd) & V4L2_STD_525_60) 1089 + core->rect.height = TVP5150_V_MAX_525_60; 1090 + else 1091 + core->rect.height = TVP5150_V_MAX_OTHERS; 1092 + core->rect.left = 0; 1093 + core->rect.width = TVP5150_H_MAX; 1094 + 1195 1095 if (debug > 1) 1196 1096 tvp5150_log_status(sd); 1197 1097 return 0; ··· 1239 1121 .id_table = tvp5150_id, 1240 1122 }; 1241 1123 1242 - static __init int init_tvp5150(void) 1243 - { 1244 - return i2c_add_driver(&tvp5150_driver); 1245 - } 1246 - 1247 - static __exit void exit_tvp5150(void) 1248 - { 1249 - i2c_del_driver(&tvp5150_driver); 1250 - } 1251 - 1252 - module_init(init_tvp5150); 1253 - module_exit(exit_tvp5150); 1124 + module_i2c_driver(tvp5150_driver);
+1 -24
drivers/media/video/tvp7002.c
··· 1069 1069 .id_table = tvp7002_id, 1070 1070 }; 1071 1071 1072 - /* 1073 - * tvp7002_init - Initialize driver via I2C interface 1074 - * 1075 - * Register the TVP7002 driver. 1076 - * Return 0 on success or error code on failure. 1077 - */ 1078 - static int __init tvp7002_init(void) 1079 - { 1080 - return i2c_add_driver(&tvp7002_driver); 1081 - } 1082 - 1083 - /* 1084 - * tvp7002_exit - Remove driver via I2C interface 1085 - * 1086 - * Unregister the TVP7002 driver. 1087 - * Returns nothing. 1088 - */ 1089 - static void __exit tvp7002_exit(void) 1090 - { 1091 - i2c_del_driver(&tvp7002_driver); 1092 - } 1093 - 1094 - module_init(tvp7002_init); 1095 - module_exit(tvp7002_exit); 1072 + module_i2c_driver(tvp7002_driver);
+1 -15
drivers/media/video/tw9910.c
··· 951 951 .id_table = tw9910_id, 952 952 }; 953 953 954 - /* 955 - * module function 956 - */ 957 - static int __init tw9910_module_init(void) 958 - { 959 - return i2c_add_driver(&tw9910_i2c_driver); 960 - } 961 - 962 - static void __exit tw9910_module_exit(void) 963 - { 964 - i2c_del_driver(&tw9910_i2c_driver); 965 - } 966 - 967 - module_init(tw9910_module_init); 968 - module_exit(tw9910_module_exit); 954 + module_i2c_driver(tw9910_i2c_driver); 969 955 970 956 MODULE_DESCRIPTION("SoC Camera driver for tw9910"); 971 957 MODULE_AUTHOR("Kuninori Morimoto");
+1 -12
drivers/media/video/upd64031a.c
··· 271 271 .id_table = upd64031a_id, 272 272 }; 273 273 274 - static __init int init_upd64031a(void) 275 - { 276 - return i2c_add_driver(&upd64031a_driver); 277 - } 278 - 279 - static __exit void exit_upd64031a(void) 280 - { 281 - i2c_del_driver(&upd64031a_driver); 282 - } 283 - 284 - module_init(init_upd64031a); 285 - module_exit(exit_upd64031a); 274 + module_i2c_driver(upd64031a_driver);
+1 -12
drivers/media/video/upd64083.c
··· 243 243 .id_table = upd64083_id, 244 244 }; 245 245 246 - static __init int init_upd64083(void) 247 - { 248 - return i2c_add_driver(&upd64083_driver); 249 - } 250 - 251 - static __exit void exit_upd64083(void) 252 - { 253 - i2c_del_driver(&upd64083_driver); 254 - } 255 - 256 - module_init(init_upd64083); 257 - module_exit(exit_upd64083); 246 + module_i2c_driver(upd64083_driver);
+10 -1
drivers/media/video/uvc/uvc_driver.c
··· 23 23 * codec can't handle MJPEG data. 24 24 */ 25 25 26 + #include <linux/atomic.h> 26 27 #include <linux/kernel.h> 27 28 #include <linux/list.h> 28 29 #include <linux/module.h> ··· 33 32 #include <linux/vmalloc.h> 34 33 #include <linux/wait.h> 35 34 #include <linux/version.h> 36 - #include <asm/atomic.h> 37 35 #include <asm/unaligned.h> 38 36 39 37 #include <media/v4l2-common.h> ··· 2139 2139 .bInterfaceSubClass = 1, 2140 2140 .bInterfaceProtocol = 0, 2141 2141 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 2142 + /* Dell XPS m1530 */ 2143 + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2144 + | USB_DEVICE_ID_MATCH_INT_INFO, 2145 + .idVendor = 0x05a9, 2146 + .idProduct = 0x2640, 2147 + .bInterfaceClass = USB_CLASS_VIDEO, 2148 + .bInterfaceSubClass = 1, 2149 + .bInterfaceProtocol = 0, 2150 + .driver_info = UVC_QUIRK_PROBE_DEF }, 2142 2151 /* Apple Built-In iSight */ 2143 2152 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2144 2153 | USB_DEVICE_ID_MATCH_INT_INFO,
+1 -1
drivers/media/video/uvc/uvc_queue.c
··· 126 126 int drop_corrupted) 127 127 { 128 128 queue->queue.type = type; 129 - queue->queue.io_modes = VB2_MMAP; 129 + queue->queue.io_modes = VB2_MMAP | VB2_USERPTR; 130 130 queue->queue.drv_priv = queue; 131 131 queue->queue.buf_struct_size = sizeof(struct uvc_buffer); 132 132 queue->queue.ops = &uvc_queue_qops;
+206 -1
drivers/media/video/uvc/uvc_v4l2.c
··· 11 11 * 12 12 */ 13 13 14 + #include <linux/compat.h> 14 15 #include <linux/kernel.h> 15 16 #include <linux/version.h> 16 17 #include <linux/list.h> ··· 1013 1012 1014 1013 default: 1015 1014 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd); 1016 - return -EINVAL; 1015 + return -ENOTTY; 1017 1016 } 1018 1017 1019 1018 return ret; ··· 1030 1029 1031 1030 return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl); 1032 1031 } 1032 + 1033 + #ifdef CONFIG_COMPAT 1034 + struct uvc_xu_control_mapping32 { 1035 + __u32 id; 1036 + __u8 name[32]; 1037 + __u8 entity[16]; 1038 + __u8 selector; 1039 + 1040 + __u8 size; 1041 + __u8 offset; 1042 + __u32 v4l2_type; 1043 + __u32 data_type; 1044 + 1045 + compat_caddr_t menu_info; 1046 + __u32 menu_count; 1047 + 1048 + __u32 reserved[4]; 1049 + }; 1050 + 1051 + static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, 1052 + const struct uvc_xu_control_mapping32 __user *up) 1053 + { 1054 + struct uvc_menu_info __user *umenus; 1055 + struct uvc_menu_info __user *kmenus; 1056 + compat_caddr_t p; 1057 + 1058 + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || 1059 + __copy_from_user(kp, up, offsetof(typeof(*up), menu_info)) || 1060 + __get_user(kp->menu_count, &up->menu_count)) 1061 + return -EFAULT; 1062 + 1063 + memset(kp->reserved, 0, sizeof(kp->reserved)); 1064 + 1065 + if (kp->menu_count == 0) { 1066 + kp->menu_info = NULL; 1067 + return 0; 1068 + } 1069 + 1070 + if (__get_user(p, &up->menu_info)) 1071 + return -EFAULT; 1072 + umenus = compat_ptr(p); 1073 + if (!access_ok(VERIFY_READ, umenus, kp->menu_count * sizeof(*umenus))) 1074 + return -EFAULT; 1075 + 1076 + kmenus = compat_alloc_user_space(kp->menu_count * sizeof(*kmenus)); 1077 + if (kmenus == NULL) 1078 + return -EFAULT; 1079 + kp->menu_info = kmenus; 1080 + 1081 + if (copy_in_user(kmenus, umenus, kp->menu_count * sizeof(*umenus))) 1082 + return -EFAULT; 1083 + 1084 + return 0; 1085 + } 1086 + 1087 + static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp, 1088 + struct uvc_xu_control_mapping32 __user *up) 1089 + { 1090 + struct uvc_menu_info __user *umenus; 1091 + struct uvc_menu_info __user *kmenus = kp->menu_info; 1092 + compat_caddr_t p; 1093 + 1094 + if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || 1095 + __copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) || 1096 + __put_user(kp->menu_count, &up->menu_count)) 1097 + return -EFAULT; 1098 + 1099 + __clear_user(up->reserved, sizeof(up->reserved)); 1100 + 1101 + if (kp->menu_count == 0) 1102 + return 0; 1103 + 1104 + if (get_user(p, &up->menu_info)) 1105 + return -EFAULT; 1106 + umenus = compat_ptr(p); 1107 + if (!access_ok(VERIFY_WRITE, umenus, kp->menu_count * sizeof(*umenus))) 1108 + return -EFAULT; 1109 + 1110 + if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus))) 1111 + return -EFAULT; 1112 + 1113 + return 0; 1114 + } 1115 + 1116 + struct uvc_xu_control_query32 { 1117 + __u8 unit; 1118 + __u8 selector; 1119 + __u8 query; 1120 + __u16 size; 1121 + compat_caddr_t data; 1122 + }; 1123 + 1124 + static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp, 1125 + const struct uvc_xu_control_query32 __user *up) 1126 + { 1127 + u8 __user *udata; 1128 + u8 __user *kdata; 1129 + compat_caddr_t p; 1130 + 1131 + if (!access_ok(VERIFY_READ, up, sizeof(*up)) || 1132 + __copy_from_user(kp, up, offsetof(typeof(*up), data))) 1133 + return -EFAULT; 1134 + 1135 + if (kp->size == 0) { 1136 + kp->data = NULL; 1137 + return 0; 1138 + } 1139 + 1140 + if (__get_user(p, &up->data)) 1141 + return -EFAULT; 1142 + udata = compat_ptr(p); 1143 + if (!access_ok(VERIFY_READ, udata, kp->size)) 1144 + return -EFAULT; 1145 + 1146 + kdata = compat_alloc_user_space(kp->size); 1147 + if (kdata == NULL) 1148 + return -EFAULT; 1149 + kp->data = kdata; 1150 + 1151 + if (copy_in_user(kdata, udata, kp->size)) 1152 + return -EFAULT; 1153 + 1154 + return 0; 1155 + } 1156 + 1157 + static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp, 1158 + struct uvc_xu_control_query32 __user *up) 1159 + { 1160 + u8 __user *udata; 1161 + u8 __user *kdata = kp->data; 1162 + compat_caddr_t p; 1163 + 1164 + if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) || 1165 + __copy_to_user(up, kp, offsetof(typeof(*up), data))) 1166 + return -EFAULT; 1167 + 1168 + if (kp->size == 0) 1169 + return 0; 1170 + 1171 + if (get_user(p, &up->data)) 1172 + return -EFAULT; 1173 + udata = compat_ptr(p); 1174 + if (!access_ok(VERIFY_READ, udata, kp->size)) 1175 + return -EFAULT; 1176 + 1177 + if (copy_in_user(udata, kdata, kp->size)) 1178 + return -EFAULT; 1179 + 1180 + return 0; 1181 + } 1182 + 1183 + #define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32) 1184 + #define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32) 1185 + 1186 + static long uvc_v4l2_compat_ioctl32(struct file *file, 1187 + unsigned int cmd, unsigned long arg) 1188 + { 1189 + union { 1190 + struct uvc_xu_control_mapping xmap; 1191 + struct uvc_xu_control_query xqry; 1192 + } karg; 1193 + void __user *up = compat_ptr(arg); 1194 + mm_segment_t old_fs; 1195 + long ret; 1196 + 1197 + switch (cmd) { 1198 + case UVCIOC_CTRL_MAP32: 1199 + cmd = UVCIOC_CTRL_MAP; 1200 + ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up); 1201 + break; 1202 + 1203 + case UVCIOC_CTRL_QUERY32: 1204 + cmd = UVCIOC_CTRL_QUERY; 1205 + ret = uvc_v4l2_get_xu_query(&karg.xqry, up); 1206 + break; 1207 + 1208 + default: 1209 + return -ENOIOCTLCMD; 1210 + } 1211 + 1212 + old_fs = get_fs(); 1213 + set_fs(KERNEL_DS); 1214 + ret = uvc_v4l2_ioctl(file, cmd, (unsigned long)&karg); 1215 + set_fs(old_fs); 1216 + 1217 + if (ret < 0) 1218 + return ret; 1219 + 1220 + switch (cmd) { 1221 + case UVCIOC_CTRL_MAP: 1222 + ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up); 1223 + break; 1224 + 1225 + case UVCIOC_CTRL_QUERY: 1226 + ret = uvc_v4l2_put_xu_query(&karg.xqry, up); 1227 + break; 1228 + } 1229 + 1230 + return ret; 1231 + } 1232 + #endif 1033 1233 1034 1234 static ssize_t uvc_v4l2_read(struct file *file, char __user *data, 1035 1235 size_t count, loff_t *ppos) ··· 1278 1076 .open = uvc_v4l2_open, 1279 1077 .release = uvc_v4l2_release, 1280 1078 .unlocked_ioctl = uvc_v4l2_ioctl, 1079 + #ifdef CONFIG_COMPAT 1080 + .compat_ioctl32 = uvc_v4l2_compat_ioctl32, 1081 + #endif 1281 1082 .read = uvc_v4l2_read, 1282 1083 .mmap = uvc_v4l2_mmap, 1283 1084 .poll = uvc_v4l2_poll,
+13 -9
drivers/media/video/v4l2-compat-ioctl32.c
··· 14 14 */ 15 15 16 16 #include <linux/compat.h> 17 - #include <linux/videodev2.h> 18 17 #include <linux/module.h> 18 + #include <linux/videodev2.h> 19 + #include <media/v4l2-dev.h> 19 20 #include <media/v4l2-ioctl.h> 20 - 21 - #ifdef CONFIG_COMPAT 22 21 23 22 static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 24 23 { ··· 936 937 937 938 long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) 938 939 { 940 + struct video_device *vdev = video_devdata(file); 939 941 long ret = -ENOIOCTLCMD; 940 942 941 943 if (!file->f_op->unlocked_ioctl) ··· 1005 1005 case VIDIOC_G_ENC_INDEX: 1006 1006 case VIDIOC_ENCODER_CMD: 1007 1007 case VIDIOC_TRY_ENCODER_CMD: 1008 + case VIDIOC_DECODER_CMD: 1009 + case VIDIOC_TRY_DECODER_CMD: 1008 1010 case VIDIOC_DBG_S_REGISTER: 1009 1011 case VIDIOC_DBG_G_REGISTER: 1010 1012 case VIDIOC_DBG_G_CHIP_IDENT: ··· 1027 1025 break; 1028 1026 1029 1027 default: 1030 - printk(KERN_WARNING "compat_ioctl32: " 1031 - "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", 1032 - _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd); 1028 + if (vdev->fops->compat_ioctl32) 1029 + ret = vdev->fops->compat_ioctl32(file, cmd, arg); 1030 + 1031 + if (ret == -ENOIOCTLCMD) 1032 + printk(KERN_WARNING "compat_ioctl32: " 1033 + "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", 1034 + _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), 1035 + cmd); 1033 1036 break; 1034 1037 } 1035 1038 return ret; 1036 1039 } 1037 1040 EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32); 1038 - #endif 1039 - 1040 - MODULE_LICENSE("GPL");
+86 -5
drivers/media/video/v4l2-ctrls.c
··· 175 175 "16-bit CRC", 176 176 NULL 177 177 }; 178 + static const char * const mpeg_audio_dec_playback[] = { 179 + "Auto", 180 + "Stereo", 181 + "Left", 182 + "Right", 183 + "Mono", 184 + "Swapped Stereo", 185 + NULL 186 + }; 178 187 static const char * const mpeg_video_encoding[] = { 179 188 "MPEG-1", 180 189 "MPEG-2", ··· 245 236 }; 246 237 static const char * const tune_preemphasis[] = { 247 238 "No Preemphasis", 248 - "50 useconds", 249 - "75 useconds", 239 + "50 Microseconds", 240 + "75 Microseconds", 250 241 NULL, 251 242 }; 252 243 static const char * const header_mode[] = { ··· 343 334 }; 344 335 static const char * const mpeg4_profile[] = { 345 336 "Simple", 346 - "Adcanved Simple", 337 + "Advanced Simple", 347 338 "Core", 348 339 "Simple Scalable", 349 340 "Advanced Coding Efficency", ··· 359 350 static const char * const flash_strobe_source[] = { 360 351 "Software", 361 352 "External", 353 + NULL, 354 + }; 355 + 356 + static const char * const jpeg_chroma_subsampling[] = { 357 + "4:4:4", 358 + "4:2:2", 359 + "4:2:0", 360 + "4:1:1", 361 + "4:1:0", 362 + "Gray", 362 363 NULL, 363 364 }; 364 365 ··· 393 374 return mpeg_audio_emphasis; 394 375 case V4L2_CID_MPEG_AUDIO_CRC: 395 376 return mpeg_audio_crc; 377 + case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: 378 + case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: 379 + return mpeg_audio_dec_playback; 396 380 case V4L2_CID_MPEG_VIDEO_ENCODING: 397 381 return mpeg_video_encoding; 398 382 case V4L2_CID_MPEG_VIDEO_ASPECT: ··· 436 414 return mpeg_mpeg4_level; 437 415 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 438 416 return mpeg4_profile; 417 + case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: 418 + return jpeg_chroma_subsampling; 419 + 439 420 default: 440 421 return NULL; 441 422 } ··· 517 492 case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute"; 518 493 case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate"; 519 494 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate"; 495 + case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: return "Audio Playback"; 496 + case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback"; 520 497 case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding"; 521 498 case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect"; 522 499 case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames"; ··· 573 546 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice"; 574 547 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method"; 575 548 case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; 549 + case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS"; 550 + case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count"; 576 551 577 552 /* CAMERA controls */ 578 553 /* Keep the order of the 'case's the same as in videodev2.h! */ ··· 635 606 case V4L2_CID_FLASH_FAULT: return "Faults"; 636 607 case V4L2_CID_FLASH_CHARGE: return "Charge"; 637 608 case V4L2_CID_FLASH_READY: return "Ready to Strobe"; 609 + 610 + /* JPEG encoder controls */ 611 + /* Keep the order of the 'case's the same as in videodev2.h! */ 612 + case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls"; 613 + case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling"; 614 + case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval"; 615 + case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality"; 616 + case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers"; 638 617 639 618 default: 640 619 return NULL; ··· 711 674 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: 712 675 case V4L2_CID_MPEG_AUDIO_EMPHASIS: 713 676 case V4L2_CID_MPEG_AUDIO_CRC: 677 + case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: 678 + case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: 714 679 case V4L2_CID_MPEG_VIDEO_ENCODING: 715 680 case V4L2_CID_MPEG_VIDEO_ASPECT: 716 681 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: ··· 732 693 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: 733 694 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: 734 695 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 696 + case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: 735 697 *type = V4L2_CTRL_TYPE_MENU; 736 698 break; 737 699 case V4L2_CID_RDS_TX_PS_NAME: ··· 744 704 case V4L2_CID_MPEG_CLASS: 745 705 case V4L2_CID_FM_TX_CLASS: 746 706 case V4L2_CID_FLASH_CLASS: 707 + case V4L2_CID_JPEG_CLASS: 747 708 *type = V4L2_CTRL_TYPE_CTRL_CLASS; 748 709 /* You can neither read not write these */ 749 710 *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY; ··· 758 717 *max = 0xFFFFFF; 759 718 break; 760 719 case V4L2_CID_FLASH_FAULT: 720 + case V4L2_CID_JPEG_ACTIVE_MARKER: 761 721 *type = V4L2_CTRL_TYPE_BITMASK; 762 722 break; 763 723 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: 764 724 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: 765 725 *type = V4L2_CTRL_TYPE_INTEGER; 766 726 *flags |= V4L2_CTRL_FLAG_READ_ONLY; 727 + break; 728 + case V4L2_CID_MPEG_VIDEO_DEC_FRAME: 729 + case V4L2_CID_MPEG_VIDEO_DEC_PTS: 730 + *type = V4L2_CTRL_TYPE_INTEGER64; 731 + *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE; 767 732 break; 768 733 default: 769 734 *type = V4L2_CTRL_TYPE_INTEGER; ··· 1517 1470 int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, 1518 1471 struct v4l2_ctrl_handler *add) 1519 1472 { 1520 - struct v4l2_ctrl *ctrl; 1473 + struct v4l2_ctrl_ref *ref; 1521 1474 int ret = 0; 1522 1475 1523 1476 /* Do nothing if either handler is NULL or if they are the same */ ··· 1526 1479 if (hdl->error) 1527 1480 return hdl->error; 1528 1481 mutex_lock(&add->lock); 1529 - list_for_each_entry(ctrl, &add->ctrls, node) { 1482 + list_for_each_entry(ref, &add->ctrl_refs, node) { 1483 + struct v4l2_ctrl *ctrl = ref->ctrl; 1484 + 1530 1485 /* Skip handler-private controls. */ 1531 1486 if (ctrl->is_private) 1532 1487 continue; ··· 2408 2359 v4l2_ctrl_unlock(ctrl); 2409 2360 } 2410 2361 EXPORT_SYMBOL(v4l2_ctrl_del_event); 2362 + 2363 + int v4l2_ctrl_log_status(struct file *file, void *fh) 2364 + { 2365 + struct video_device *vfd = video_devdata(file); 2366 + struct v4l2_fh *vfh = file->private_data; 2367 + 2368 + if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev) 2369 + v4l2_ctrl_handler_log_status(vfh->ctrl_handler, 2370 + vfd->v4l2_dev->name); 2371 + return 0; 2372 + } 2373 + EXPORT_SYMBOL(v4l2_ctrl_log_status); 2374 + 2375 + int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh, 2376 + struct v4l2_event_subscription *sub) 2377 + { 2378 + if (sub->type == V4L2_EVENT_CTRL) 2379 + return v4l2_event_subscribe(fh, sub, 0); 2380 + return -EINVAL; 2381 + } 2382 + EXPORT_SYMBOL(v4l2_ctrl_subscribe_event); 2383 + 2384 + unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait) 2385 + { 2386 + struct v4l2_fh *fh = file->private_data; 2387 + 2388 + if (v4l2_event_pending(fh)) 2389 + return POLLPRI; 2390 + poll_wait(file, &fh->wait, wait); 2391 + return 0; 2392 + } 2393 + EXPORT_SYMBOL(v4l2_ctrl_poll);
+1 -1
drivers/media/video/v4l2-dev.c
··· 788 788 unregister_chrdev_region(dev, VIDEO_NUM_DEVICES); 789 789 } 790 790 791 - module_init(videodev_init) 791 + subsys_initcall(videodev_init); 792 792 module_exit(videodev_exit) 793 793 794 794 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
+39 -3
drivers/media/video/v4l2-ioctl.c
··· 260 260 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", 261 261 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", 262 262 263 + [_IOC_NR(VIDIOC_DECODER_CMD)] = "VIDIOC_DECODER_CMD", 264 + [_IOC_NR(VIDIOC_TRY_DECODER_CMD)] = "VIDIOC_TRY_DECODER_CMD", 263 265 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", 264 266 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", 265 267 ··· 542 540 if (!ret) 543 541 dbgarg(cmd, "driver=%s, card=%s, bus=%s, " 544 542 "version=0x%08x, " 545 - "capabilities=0x%08x\n", 543 + "capabilities=0x%08x, " 544 + "device_caps=0x%08x\n", 546 545 cap->driver, cap->card, cap->bus_info, 547 546 cap->version, 548 - cap->capabilities); 547 + cap->capabilities, 548 + cap->device_caps); 549 549 break; 550 550 } 551 551 ··· 1766 1762 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1767 1763 break; 1768 1764 } 1765 + case VIDIOC_DECODER_CMD: 1766 + { 1767 + struct v4l2_decoder_cmd *p = arg; 1768 + 1769 + if (!ops->vidioc_decoder_cmd) 1770 + break; 1771 + if (ret_prio) { 1772 + ret = ret_prio; 1773 + break; 1774 + } 1775 + ret = ops->vidioc_decoder_cmd(file, fh, p); 1776 + if (!ret) 1777 + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1778 + break; 1779 + } 1780 + case VIDIOC_TRY_DECODER_CMD: 1781 + { 1782 + struct v4l2_decoder_cmd *p = arg; 1783 + 1784 + if (!ops->vidioc_try_decoder_cmd) 1785 + break; 1786 + ret = ops->vidioc_try_decoder_cmd(file, fh, p); 1787 + if (!ret) 1788 + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1789 + break; 1790 + } 1769 1791 case VIDIOC_G_PARM: 1770 1792 { 1771 1793 struct v4l2_streamparm *p = arg; ··· 1939 1909 { 1940 1910 if (!ops->vidioc_log_status) 1941 1911 break; 1912 + if (vfd->v4l2_dev) 1913 + pr_info("%s: ================= START STATUS =================\n", 1914 + vfd->v4l2_dev->name); 1942 1915 ret = ops->vidioc_log_status(file, fh); 1916 + if (vfd->v4l2_dev) 1917 + pr_info("%s: ================== END STATUS ==================\n", 1918 + vfd->v4l2_dev->name); 1943 1919 break; 1944 1920 } 1945 1921 #ifdef CONFIG_VIDEO_ADV_DEBUG ··· 2455 2419 /* Handles IOCTL */ 2456 2420 err = func(file, cmd, parg); 2457 2421 if (err == -ENOIOCTLCMD) 2458 - err = -EINVAL; 2422 + err = -ENOTTY; 2459 2423 2460 2424 if (has_array_args) { 2461 2425 *kernel_ptr = user_ptr;
+10 -2
drivers/media/video/v4l2-subdev.c
··· 194 194 } 195 195 #endif 196 196 197 - case VIDIOC_LOG_STATUS: 198 - return v4l2_subdev_call(sd, core, log_status); 197 + case VIDIOC_LOG_STATUS: { 198 + int ret; 199 + 200 + pr_info("%s: ================= START STATUS =================\n", 201 + sd->name); 202 + ret = v4l2_subdev_call(sd, core, log_status); 203 + pr_info("%s: ================== END STATUS ==================\n", 204 + sd->name); 205 + return ret; 206 + } 199 207 200 208 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 201 209 case VIDIOC_SUBDEV_G_FMT: {
+46 -22
drivers/media/video/videobuf2-vmalloc.c
··· 10 10 * the Free Software Foundation. 11 11 */ 12 12 13 + #include <linux/io.h> 13 14 #include <linux/module.h> 14 15 #include <linux/mm.h> 15 16 #include <linux/sched.h> ··· 23 22 struct vb2_vmalloc_buf { 24 23 void *vaddr; 25 24 struct page **pages; 25 + struct vm_area_struct *vma; 26 26 int write; 27 27 unsigned long size; 28 28 unsigned int n_pages; ··· 73 71 struct vb2_vmalloc_buf *buf; 74 72 unsigned long first, last; 75 73 int n_pages, offset; 74 + struct vm_area_struct *vma; 75 + dma_addr_t physp; 76 76 77 77 buf = kzalloc(sizeof(*buf), GFP_KERNEL); 78 78 if (!buf) ··· 84 80 offset = vaddr & ~PAGE_MASK; 85 81 buf->size = size; 86 82 87 - first = vaddr >> PAGE_SHIFT; 88 - last = (vaddr + size - 1) >> PAGE_SHIFT; 89 - buf->n_pages = last - first + 1; 90 - buf->pages = kzalloc(buf->n_pages * sizeof(struct page *), GFP_KERNEL); 91 - if (!buf->pages) 92 - goto fail_pages_array_alloc; 93 83 94 - /* current->mm->mmap_sem is taken by videobuf2 core */ 95 - n_pages = get_user_pages(current, current->mm, vaddr & PAGE_MASK, 96 - buf->n_pages, write, 1, /* force */ 97 - buf->pages, NULL); 98 - if (n_pages != buf->n_pages) 99 - goto fail_get_user_pages; 84 + vma = find_vma(current->mm, vaddr); 85 + if (vma && (vma->vm_flags & VM_PFNMAP) && (vma->vm_pgoff)) { 86 + if (vb2_get_contig_userptr(vaddr, size, &vma, &physp)) 87 + goto fail_pages_array_alloc; 88 + buf->vma = vma; 89 + buf->vaddr = ioremap_nocache(physp, size); 90 + if (!buf->vaddr) 91 + goto fail_pages_array_alloc; 92 + } else { 93 + first = vaddr >> PAGE_SHIFT; 94 + last = (vaddr + size - 1) >> PAGE_SHIFT; 95 + buf->n_pages = last - first + 1; 96 + buf->pages = kzalloc(buf->n_pages * sizeof(struct page *), 97 + GFP_KERNEL); 98 + if (!buf->pages) 99 + goto fail_pages_array_alloc; 100 100 101 - buf->vaddr = vm_map_ram(buf->pages, buf->n_pages, -1, PAGE_KERNEL); 102 - if (!buf->vaddr) 103 - goto fail_get_user_pages; 101 + /* current->mm->mmap_sem is taken by videobuf2 core */ 102 + n_pages = get_user_pages(current, current->mm, 103 + vaddr & PAGE_MASK, buf->n_pages, 104 + write, 1, /* force */ 105 + buf->pages, NULL); 106 + if (n_pages != buf->n_pages) 107 + goto fail_get_user_pages; 108 + 109 + buf->vaddr = vm_map_ram(buf->pages, buf->n_pages, -1, 110 + PAGE_KERNEL); 111 + if (!buf->vaddr) 112 + goto fail_get_user_pages; 113 + } 104 114 105 115 buf->vaddr += offset; 106 116 return buf; ··· 138 120 unsigned long vaddr = (unsigned long)buf->vaddr & PAGE_MASK; 139 121 unsigned int i; 140 122 141 - if (vaddr) 142 - vm_unmap_ram((void *)vaddr, buf->n_pages); 143 - for (i = 0; i < buf->n_pages; ++i) { 144 - if (buf->write) 145 - set_page_dirty_lock(buf->pages[i]); 146 - put_page(buf->pages[i]); 123 + if (buf->pages) { 124 + if (vaddr) 125 + vm_unmap_ram((void *)vaddr, buf->n_pages); 126 + for (i = 0; i < buf->n_pages; ++i) { 127 + if (buf->write) 128 + set_page_dirty_lock(buf->pages[i]); 129 + put_page(buf->pages[i]); 130 + } 131 + kfree(buf->pages); 132 + } else { 133 + if (buf->vma) 134 + vb2_put_vma(buf->vma); 135 + iounmap(buf->vaddr); 147 136 } 148 - kfree(buf->pages); 149 137 kfree(buf); 150 138 } 151 139
+4 -22
drivers/media/video/vivi.c
··· 819 819 strcpy(cap->driver, "vivi"); 820 820 strcpy(cap->card, "vivi"); 821 821 strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); 822 - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \ 822 + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | 823 823 V4L2_CAP_READWRITE; 824 + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; 824 825 return 0; 825 826 } 826 827 ··· 959 958 return vb2_streamoff(&dev->vb_vidq, i); 960 959 } 961 960 962 - static int vidioc_log_status(struct file *file, void *priv) 963 - { 964 - struct vivi_dev *dev = video_drvdata(file); 965 - 966 - v4l2_ctrl_handler_log_status(&dev->ctrl_handler, dev->v4l2_dev.name); 967 - return 0; 968 - } 969 - 970 961 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) 971 962 { 972 963 return 0; ··· 999 1006 precalculate_bars(dev); 1000 1007 precalculate_line(dev); 1001 1008 return 0; 1002 - } 1003 - 1004 - static int vidioc_subscribe_event(struct v4l2_fh *fh, 1005 - struct v4l2_event_subscription *sub) 1006 - { 1007 - switch (sub->type) { 1008 - case V4L2_EVENT_CTRL: 1009 - return v4l2_event_subscribe(fh, sub, 0); 1010 - default: 1011 - return -EINVAL; 1012 - } 1013 1009 } 1014 1010 1015 1011 /* --- controls ---------------------------------------------- */ ··· 1191 1209 .vidioc_s_input = vidioc_s_input, 1192 1210 .vidioc_streamon = vidioc_streamon, 1193 1211 .vidioc_streamoff = vidioc_streamoff, 1194 - .vidioc_log_status = vidioc_log_status, 1195 - .vidioc_subscribe_event = vidioc_subscribe_event, 1212 + .vidioc_log_status = v4l2_ctrl_log_status, 1213 + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 1196 1214 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 1197 1215 }; 1198 1216
+1 -12
drivers/media/video/vp27smpx.c
··· 208 208 .id_table = vp27smpx_id, 209 209 }; 210 210 211 - static __init int init_vp27smpx(void) 212 - { 213 - return i2c_add_driver(&vp27smpx_driver); 214 - } 215 - 216 - static __exit void exit_vp27smpx(void) 217 - { 218 - i2c_del_driver(&vp27smpx_driver); 219 - } 220 - 221 - module_init(init_vp27smpx); 222 - module_exit(exit_vp27smpx); 211 + module_i2c_driver(vp27smpx_driver);
+1 -12
drivers/media/video/vpx3220.c
··· 588 588 .id_table = vpx3220_id, 589 589 }; 590 590 591 - static __init int init_vpx3220(void) 592 - { 593 - return i2c_add_driver(&vpx3220_driver); 594 - } 595 - 596 - static __exit void exit_vpx3220(void) 597 - { 598 - i2c_del_driver(&vpx3220_driver); 599 - } 600 - 601 - module_init(init_vpx3220); 602 - module_exit(exit_vpx3220); 591 + module_i2c_driver(vpx3220_driver);
+928
drivers/media/video/vs6624.c
··· 1 + /* 2 + * vs6624.c ST VS6624 CMOS image sensor driver 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 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 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #include <linux/delay.h> 21 + #include <linux/errno.h> 22 + #include <linux/gpio.h> 23 + #include <linux/i2c.h> 24 + #include <linux/init.h> 25 + #include <linux/module.h> 26 + #include <linux/slab.h> 27 + #include <linux/types.h> 28 + #include <linux/videodev2.h> 29 + 30 + #include <media/v4l2-chip-ident.h> 31 + #include <media/v4l2-ctrls.h> 32 + #include <media/v4l2-device.h> 33 + #include <media/v4l2-mediabus.h> 34 + 35 + #include "vs6624_regs.h" 36 + 37 + #define VGA_WIDTH 640 38 + #define VGA_HEIGHT 480 39 + #define QVGA_WIDTH 320 40 + #define QVGA_HEIGHT 240 41 + #define QQVGA_WIDTH 160 42 + #define QQVGA_HEIGHT 120 43 + #define CIF_WIDTH 352 44 + #define CIF_HEIGHT 288 45 + #define QCIF_WIDTH 176 46 + #define QCIF_HEIGHT 144 47 + #define QQCIF_WIDTH 88 48 + #define QQCIF_HEIGHT 72 49 + 50 + #define MAX_FRAME_RATE 30 51 + 52 + struct vs6624 { 53 + struct v4l2_subdev sd; 54 + struct v4l2_ctrl_handler hdl; 55 + struct v4l2_fract frame_rate; 56 + struct v4l2_mbus_framefmt fmt; 57 + unsigned ce_pin; 58 + }; 59 + 60 + static const struct vs6624_format { 61 + enum v4l2_mbus_pixelcode mbus_code; 62 + enum v4l2_colorspace colorspace; 63 + } vs6624_formats[] = { 64 + { 65 + .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, 66 + .colorspace = V4L2_COLORSPACE_JPEG, 67 + }, 68 + { 69 + .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, 70 + .colorspace = V4L2_COLORSPACE_JPEG, 71 + }, 72 + { 73 + .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, 74 + .colorspace = V4L2_COLORSPACE_SRGB, 75 + }, 76 + }; 77 + 78 + static struct v4l2_mbus_framefmt vs6624_default_fmt = { 79 + .width = VGA_WIDTH, 80 + .height = VGA_HEIGHT, 81 + .code = V4L2_MBUS_FMT_UYVY8_2X8, 82 + .field = V4L2_FIELD_NONE, 83 + .colorspace = V4L2_COLORSPACE_JPEG, 84 + }; 85 + 86 + static const u16 vs6624_p1[] = { 87 + 0x8104, 0x03, 88 + 0x8105, 0x01, 89 + 0xc900, 0x03, 90 + 0xc904, 0x47, 91 + 0xc905, 0x10, 92 + 0xc906, 0x80, 93 + 0xc907, 0x3a, 94 + 0x903a, 0x02, 95 + 0x903b, 0x47, 96 + 0x903c, 0x15, 97 + 0xc908, 0x31, 98 + 0xc909, 0xdc, 99 + 0xc90a, 0x80, 100 + 0xc90b, 0x44, 101 + 0x9044, 0x02, 102 + 0x9045, 0x31, 103 + 0x9046, 0xe2, 104 + 0xc90c, 0x07, 105 + 0xc90d, 0xe0, 106 + 0xc90e, 0x80, 107 + 0xc90f, 0x47, 108 + 0x9047, 0x90, 109 + 0x9048, 0x83, 110 + 0x9049, 0x81, 111 + 0x904a, 0xe0, 112 + 0x904b, 0x60, 113 + 0x904c, 0x08, 114 + 0x904d, 0x90, 115 + 0x904e, 0xc0, 116 + 0x904f, 0x43, 117 + 0x9050, 0x74, 118 + 0x9051, 0x01, 119 + 0x9052, 0xf0, 120 + 0x9053, 0x80, 121 + 0x9054, 0x05, 122 + 0x9055, 0xE4, 123 + 0x9056, 0x90, 124 + 0x9057, 0xc0, 125 + 0x9058, 0x43, 126 + 0x9059, 0xf0, 127 + 0x905a, 0x02, 128 + 0x905b, 0x07, 129 + 0x905c, 0xec, 130 + 0xc910, 0x5d, 131 + 0xc911, 0xca, 132 + 0xc912, 0x80, 133 + 0xc913, 0x5d, 134 + 0x905d, 0xa3, 135 + 0x905e, 0x04, 136 + 0x905f, 0xf0, 137 + 0x9060, 0xa3, 138 + 0x9061, 0x04, 139 + 0x9062, 0xf0, 140 + 0x9063, 0x22, 141 + 0xc914, 0x72, 142 + 0xc915, 0x92, 143 + 0xc916, 0x80, 144 + 0xc917, 0x64, 145 + 0x9064, 0x74, 146 + 0x9065, 0x01, 147 + 0x9066, 0x02, 148 + 0x9067, 0x72, 149 + 0x9068, 0x95, 150 + 0xc918, 0x47, 151 + 0xc919, 0xf2, 152 + 0xc91a, 0x81, 153 + 0xc91b, 0x69, 154 + 0x9169, 0x74, 155 + 0x916a, 0x02, 156 + 0x916b, 0xf0, 157 + 0x916c, 0xec, 158 + 0x916d, 0xb4, 159 + 0x916e, 0x10, 160 + 0x916f, 0x0a, 161 + 0x9170, 0x90, 162 + 0x9171, 0x80, 163 + 0x9172, 0x16, 164 + 0x9173, 0xe0, 165 + 0x9174, 0x70, 166 + 0x9175, 0x04, 167 + 0x9176, 0x90, 168 + 0x9177, 0xd3, 169 + 0x9178, 0xc4, 170 + 0x9179, 0xf0, 171 + 0x917a, 0x22, 172 + 0xc91c, 0x0a, 173 + 0xc91d, 0xbe, 174 + 0xc91e, 0x80, 175 + 0xc91f, 0x73, 176 + 0x9073, 0xfc, 177 + 0x9074, 0xa3, 178 + 0x9075, 0xe0, 179 + 0x9076, 0xf5, 180 + 0x9077, 0x82, 181 + 0x9078, 0x8c, 182 + 0x9079, 0x83, 183 + 0x907a, 0xa3, 184 + 0x907b, 0xa3, 185 + 0x907c, 0xe0, 186 + 0x907d, 0xfc, 187 + 0x907e, 0xa3, 188 + 0x907f, 0xe0, 189 + 0x9080, 0xc3, 190 + 0x9081, 0x9f, 191 + 0x9082, 0xff, 192 + 0x9083, 0xec, 193 + 0x9084, 0x9e, 194 + 0x9085, 0xfe, 195 + 0x9086, 0x02, 196 + 0x9087, 0x0a, 197 + 0x9088, 0xea, 198 + 0xc920, 0x47, 199 + 0xc921, 0x38, 200 + 0xc922, 0x80, 201 + 0xc923, 0x89, 202 + 0x9089, 0xec, 203 + 0x908a, 0xd3, 204 + 0x908b, 0x94, 205 + 0x908c, 0x20, 206 + 0x908d, 0x40, 207 + 0x908e, 0x01, 208 + 0x908f, 0x1c, 209 + 0x9090, 0x90, 210 + 0x9091, 0xd3, 211 + 0x9092, 0xd4, 212 + 0x9093, 0xec, 213 + 0x9094, 0xf0, 214 + 0x9095, 0x02, 215 + 0x9096, 0x47, 216 + 0x9097, 0x3d, 217 + 0xc924, 0x45, 218 + 0xc925, 0xca, 219 + 0xc926, 0x80, 220 + 0xc927, 0x98, 221 + 0x9098, 0x12, 222 + 0x9099, 0x77, 223 + 0x909a, 0xd6, 224 + 0x909b, 0x02, 225 + 0x909c, 0x45, 226 + 0x909d, 0xcd, 227 + 0xc928, 0x20, 228 + 0xc929, 0xd5, 229 + 0xc92a, 0x80, 230 + 0xc92b, 0x9e, 231 + 0x909e, 0x90, 232 + 0x909f, 0x82, 233 + 0x90a0, 0x18, 234 + 0x90a1, 0xe0, 235 + 0x90a2, 0xb4, 236 + 0x90a3, 0x03, 237 + 0x90a4, 0x0e, 238 + 0x90a5, 0x90, 239 + 0x90a6, 0x83, 240 + 0x90a7, 0xbf, 241 + 0x90a8, 0xe0, 242 + 0x90a9, 0x60, 243 + 0x90aa, 0x08, 244 + 0x90ab, 0x90, 245 + 0x90ac, 0x81, 246 + 0x90ad, 0xfc, 247 + 0x90ae, 0xe0, 248 + 0x90af, 0xff, 249 + 0x90b0, 0xc3, 250 + 0x90b1, 0x13, 251 + 0x90b2, 0xf0, 252 + 0x90b3, 0x90, 253 + 0x90b4, 0x81, 254 + 0x90b5, 0xfc, 255 + 0x90b6, 0xe0, 256 + 0x90b7, 0xff, 257 + 0x90b8, 0x02, 258 + 0x90b9, 0x20, 259 + 0x90ba, 0xda, 260 + 0xc92c, 0x70, 261 + 0xc92d, 0xbc, 262 + 0xc92e, 0x80, 263 + 0xc92f, 0xbb, 264 + 0x90bb, 0x90, 265 + 0x90bc, 0x82, 266 + 0x90bd, 0x18, 267 + 0x90be, 0xe0, 268 + 0x90bf, 0xb4, 269 + 0x90c0, 0x03, 270 + 0x90c1, 0x06, 271 + 0x90c2, 0x90, 272 + 0x90c3, 0xc1, 273 + 0x90c4, 0x06, 274 + 0x90c5, 0x74, 275 + 0x90c6, 0x05, 276 + 0x90c7, 0xf0, 277 + 0x90c8, 0x90, 278 + 0x90c9, 0xd3, 279 + 0x90ca, 0xa0, 280 + 0x90cb, 0x02, 281 + 0x90cc, 0x70, 282 + 0x90cd, 0xbf, 283 + 0xc930, 0x72, 284 + 0xc931, 0x21, 285 + 0xc932, 0x81, 286 + 0xc933, 0x3b, 287 + 0x913b, 0x7d, 288 + 0x913c, 0x02, 289 + 0x913d, 0x7f, 290 + 0x913e, 0x7b, 291 + 0x913f, 0x02, 292 + 0x9140, 0x72, 293 + 0x9141, 0x25, 294 + 0xc934, 0x28, 295 + 0xc935, 0xae, 296 + 0xc936, 0x80, 297 + 0xc937, 0xd2, 298 + 0x90d2, 0xf0, 299 + 0x90d3, 0x90, 300 + 0x90d4, 0xd2, 301 + 0x90d5, 0x0a, 302 + 0x90d6, 0x02, 303 + 0x90d7, 0x28, 304 + 0x90d8, 0xb4, 305 + 0xc938, 0x28, 306 + 0xc939, 0xb1, 307 + 0xc93a, 0x80, 308 + 0xc93b, 0xd9, 309 + 0x90d9, 0x90, 310 + 0x90da, 0x83, 311 + 0x90db, 0xba, 312 + 0x90dc, 0xe0, 313 + 0x90dd, 0xff, 314 + 0x90de, 0x90, 315 + 0x90df, 0xd2, 316 + 0x90e0, 0x08, 317 + 0x90e1, 0xe0, 318 + 0x90e2, 0xe4, 319 + 0x90e3, 0xef, 320 + 0x90e4, 0xf0, 321 + 0x90e5, 0xa3, 322 + 0x90e6, 0xe0, 323 + 0x90e7, 0x74, 324 + 0x90e8, 0xff, 325 + 0x90e9, 0xf0, 326 + 0x90ea, 0x90, 327 + 0x90eb, 0xd2, 328 + 0x90ec, 0x0a, 329 + 0x90ed, 0x02, 330 + 0x90ee, 0x28, 331 + 0x90ef, 0xb4, 332 + 0xc93c, 0x29, 333 + 0xc93d, 0x79, 334 + 0xc93e, 0x80, 335 + 0xc93f, 0xf0, 336 + 0x90f0, 0xf0, 337 + 0x90f1, 0x90, 338 + 0x90f2, 0xd2, 339 + 0x90f3, 0x0e, 340 + 0x90f4, 0x02, 341 + 0x90f5, 0x29, 342 + 0x90f6, 0x7f, 343 + 0xc940, 0x29, 344 + 0xc941, 0x7c, 345 + 0xc942, 0x80, 346 + 0xc943, 0xf7, 347 + 0x90f7, 0x90, 348 + 0x90f8, 0x83, 349 + 0x90f9, 0xba, 350 + 0x90fa, 0xe0, 351 + 0x90fb, 0xff, 352 + 0x90fc, 0x90, 353 + 0x90fd, 0xd2, 354 + 0x90fe, 0x0c, 355 + 0x90ff, 0xe0, 356 + 0x9100, 0xe4, 357 + 0x9101, 0xef, 358 + 0x9102, 0xf0, 359 + 0x9103, 0xa3, 360 + 0x9104, 0xe0, 361 + 0x9105, 0x74, 362 + 0x9106, 0xff, 363 + 0x9107, 0xf0, 364 + 0x9108, 0x90, 365 + 0x9109, 0xd2, 366 + 0x910a, 0x0e, 367 + 0x910b, 0x02, 368 + 0x910c, 0x29, 369 + 0x910d, 0x7f, 370 + 0xc944, 0x2a, 371 + 0xc945, 0x42, 372 + 0xc946, 0x81, 373 + 0xc947, 0x0e, 374 + 0x910e, 0xf0, 375 + 0x910f, 0x90, 376 + 0x9110, 0xd2, 377 + 0x9111, 0x12, 378 + 0x9112, 0x02, 379 + 0x9113, 0x2a, 380 + 0x9114, 0x48, 381 + 0xc948, 0x2a, 382 + 0xc949, 0x45, 383 + 0xc94a, 0x81, 384 + 0xc94b, 0x15, 385 + 0x9115, 0x90, 386 + 0x9116, 0x83, 387 + 0x9117, 0xba, 388 + 0x9118, 0xe0, 389 + 0x9119, 0xff, 390 + 0x911a, 0x90, 391 + 0x911b, 0xd2, 392 + 0x911c, 0x10, 393 + 0x911d, 0xe0, 394 + 0x911e, 0xe4, 395 + 0x911f, 0xef, 396 + 0x9120, 0xf0, 397 + 0x9121, 0xa3, 398 + 0x9122, 0xe0, 399 + 0x9123, 0x74, 400 + 0x9124, 0xff, 401 + 0x9125, 0xf0, 402 + 0x9126, 0x90, 403 + 0x9127, 0xd2, 404 + 0x9128, 0x12, 405 + 0x9129, 0x02, 406 + 0x912a, 0x2a, 407 + 0x912b, 0x48, 408 + 0xc900, 0x01, 409 + 0x0000, 0x00, 410 + }; 411 + 412 + static const u16 vs6624_p2[] = { 413 + 0x806f, 0x01, 414 + 0x058c, 0x01, 415 + 0x0000, 0x00, 416 + }; 417 + 418 + static const u16 vs6624_run_setup[] = { 419 + 0x1d18, 0x00, /* Enableconstrainedwhitebalance */ 420 + VS6624_PEAK_MIN_OUT_G_MSB, 0x3c, /* Damper PeakGain Output MSB */ 421 + VS6624_PEAK_MIN_OUT_G_LSB, 0x66, /* Damper PeakGain Output LSB */ 422 + VS6624_CM_LOW_THR_MSB, 0x65, /* Damper Low MSB */ 423 + VS6624_CM_LOW_THR_LSB, 0xd1, /* Damper Low LSB */ 424 + VS6624_CM_HIGH_THR_MSB, 0x66, /* Damper High MSB */ 425 + VS6624_CM_HIGH_THR_LSB, 0x62, /* Damper High LSB */ 426 + VS6624_CM_MIN_OUT_MSB, 0x00, /* Damper Min output MSB */ 427 + VS6624_CM_MIN_OUT_LSB, 0x00, /* Damper Min output LSB */ 428 + VS6624_NORA_DISABLE, 0x00, /* Nora fDisable */ 429 + VS6624_NORA_USAGE, 0x04, /* Nora usage */ 430 + VS6624_NORA_LOW_THR_MSB, 0x63, /* Damper Low MSB Changed 0x63 to 0x65 */ 431 + VS6624_NORA_LOW_THR_LSB, 0xd1, /* Damper Low LSB */ 432 + VS6624_NORA_HIGH_THR_MSB, 0x68, /* Damper High MSB */ 433 + VS6624_NORA_HIGH_THR_LSB, 0xdd, /* Damper High LSB */ 434 + VS6624_NORA_MIN_OUT_MSB, 0x3a, /* Damper Min output MSB */ 435 + VS6624_NORA_MIN_OUT_LSB, 0x00, /* Damper Min output LSB */ 436 + VS6624_F2B_DISABLE, 0x00, /* Disable */ 437 + 0x1d8a, 0x30, /* MAXWeightHigh */ 438 + 0x1d91, 0x62, /* fpDamperLowThresholdHigh MSB */ 439 + 0x1d92, 0x4a, /* fpDamperLowThresholdHigh LSB */ 440 + 0x1d95, 0x65, /* fpDamperHighThresholdHigh MSB */ 441 + 0x1d96, 0x0e, /* fpDamperHighThresholdHigh LSB */ 442 + 0x1da1, 0x3a, /* fpMinimumDamperOutputLow MSB */ 443 + 0x1da2, 0xb8, /* fpMinimumDamperOutputLow LSB */ 444 + 0x1e08, 0x06, /* MAXWeightLow */ 445 + 0x1e0a, 0x0a, /* MAXWeightHigh */ 446 + 0x1601, 0x3a, /* Red A MSB */ 447 + 0x1602, 0x14, /* Red A LSB */ 448 + 0x1605, 0x3b, /* Blue A MSB */ 449 + 0x1606, 0x85, /* BLue A LSB */ 450 + 0x1609, 0x3b, /* RED B MSB */ 451 + 0x160a, 0x85, /* RED B LSB */ 452 + 0x160d, 0x3a, /* Blue B MSB */ 453 + 0x160e, 0x14, /* Blue B LSB */ 454 + 0x1611, 0x30, /* Max Distance from Locus MSB */ 455 + 0x1612, 0x8f, /* Max Distance from Locus MSB */ 456 + 0x1614, 0x01, /* Enable constrainer */ 457 + 0x0000, 0x00, 458 + }; 459 + 460 + static const u16 vs6624_default[] = { 461 + VS6624_CONTRAST0, 0x84, 462 + VS6624_SATURATION0, 0x75, 463 + VS6624_GAMMA0, 0x11, 464 + VS6624_CONTRAST1, 0x84, 465 + VS6624_SATURATION1, 0x75, 466 + VS6624_GAMMA1, 0x11, 467 + VS6624_MAN_RG, 0x80, 468 + VS6624_MAN_GG, 0x80, 469 + VS6624_MAN_BG, 0x80, 470 + VS6624_WB_MODE, 0x1, 471 + VS6624_EXPO_COMPENSATION, 0xfe, 472 + VS6624_EXPO_METER, 0x0, 473 + VS6624_LIGHT_FREQ, 0x64, 474 + VS6624_PEAK_GAIN, 0xe, 475 + VS6624_PEAK_LOW_THR, 0x28, 476 + VS6624_HMIRROR0, 0x0, 477 + VS6624_VFLIP0, 0x0, 478 + VS6624_ZOOM_HSTEP0_MSB, 0x0, 479 + VS6624_ZOOM_HSTEP0_LSB, 0x1, 480 + VS6624_ZOOM_VSTEP0_MSB, 0x0, 481 + VS6624_ZOOM_VSTEP0_LSB, 0x1, 482 + VS6624_PAN_HSTEP0_MSB, 0x0, 483 + VS6624_PAN_HSTEP0_LSB, 0xf, 484 + VS6624_PAN_VSTEP0_MSB, 0x0, 485 + VS6624_PAN_VSTEP0_LSB, 0xf, 486 + VS6624_SENSOR_MODE, 0x1, 487 + VS6624_SYNC_CODE_SETUP, 0x21, 488 + VS6624_DISABLE_FR_DAMPER, 0x0, 489 + VS6624_FR_DEN, 0x1, 490 + VS6624_FR_NUM_LSB, 0xf, 491 + VS6624_INIT_PIPE_SETUP, 0x0, 492 + VS6624_IMG_FMT0, 0x0, 493 + VS6624_YUV_SETUP, 0x1, 494 + VS6624_IMAGE_SIZE0, 0x2, 495 + 0x0000, 0x00, 496 + }; 497 + 498 + static inline struct vs6624 *to_vs6624(struct v4l2_subdev *sd) 499 + { 500 + return container_of(sd, struct vs6624, sd); 501 + } 502 + static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) 503 + { 504 + return &container_of(ctrl->handler, struct vs6624, hdl)->sd; 505 + } 506 + 507 + static int vs6624_read(struct v4l2_subdev *sd, u16 index) 508 + { 509 + struct i2c_client *client = v4l2_get_subdevdata(sd); 510 + u8 buf[2]; 511 + 512 + buf[0] = index >> 8; 513 + buf[1] = index; 514 + i2c_master_send(client, buf, 2); 515 + i2c_master_recv(client, buf, 1); 516 + 517 + return buf[0]; 518 + } 519 + 520 + static int vs6624_write(struct v4l2_subdev *sd, u16 index, 521 + u8 value) 522 + { 523 + struct i2c_client *client = v4l2_get_subdevdata(sd); 524 + u8 buf[3]; 525 + 526 + buf[0] = index >> 8; 527 + buf[1] = index; 528 + buf[2] = value; 529 + 530 + return i2c_master_send(client, buf, 3); 531 + } 532 + 533 + static int vs6624_writeregs(struct v4l2_subdev *sd, const u16 *regs) 534 + { 535 + u16 reg; 536 + u8 data; 537 + 538 + while (*regs != 0x00) { 539 + reg = *regs++; 540 + data = *regs++; 541 + 542 + vs6624_write(sd, reg, data); 543 + } 544 + return 0; 545 + } 546 + 547 + static int vs6624_s_ctrl(struct v4l2_ctrl *ctrl) 548 + { 549 + struct v4l2_subdev *sd = to_sd(ctrl); 550 + 551 + switch (ctrl->id) { 552 + case V4L2_CID_CONTRAST: 553 + vs6624_write(sd, VS6624_CONTRAST0, ctrl->val); 554 + break; 555 + case V4L2_CID_SATURATION: 556 + vs6624_write(sd, VS6624_SATURATION0, ctrl->val); 557 + break; 558 + case V4L2_CID_HFLIP: 559 + vs6624_write(sd, VS6624_HMIRROR0, ctrl->val); 560 + break; 561 + case V4L2_CID_VFLIP: 562 + vs6624_write(sd, VS6624_VFLIP0, ctrl->val); 563 + break; 564 + default: 565 + return -EINVAL; 566 + } 567 + 568 + return 0; 569 + } 570 + 571 + static int vs6624_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, 572 + enum v4l2_mbus_pixelcode *code) 573 + { 574 + if (index >= ARRAY_SIZE(vs6624_formats)) 575 + return -EINVAL; 576 + 577 + *code = vs6624_formats[index].mbus_code; 578 + return 0; 579 + } 580 + 581 + static int vs6624_try_mbus_fmt(struct v4l2_subdev *sd, 582 + struct v4l2_mbus_framefmt *fmt) 583 + { 584 + int index; 585 + 586 + for (index = 0; index < ARRAY_SIZE(vs6624_formats); index++) 587 + if (vs6624_formats[index].mbus_code == fmt->code) 588 + break; 589 + if (index >= ARRAY_SIZE(vs6624_formats)) { 590 + /* default to first format */ 591 + index = 0; 592 + fmt->code = vs6624_formats[0].mbus_code; 593 + } 594 + 595 + /* sensor mode is VGA */ 596 + if (fmt->width > VGA_WIDTH) 597 + fmt->width = VGA_WIDTH; 598 + if (fmt->height > VGA_HEIGHT) 599 + fmt->height = VGA_HEIGHT; 600 + fmt->width = fmt->width & (~3); 601 + fmt->height = fmt->height & (~3); 602 + fmt->field = V4L2_FIELD_NONE; 603 + fmt->colorspace = vs6624_formats[index].colorspace; 604 + return 0; 605 + } 606 + 607 + static int vs6624_s_mbus_fmt(struct v4l2_subdev *sd, 608 + struct v4l2_mbus_framefmt *fmt) 609 + { 610 + struct vs6624 *sensor = to_vs6624(sd); 611 + int ret; 612 + 613 + ret = vs6624_try_mbus_fmt(sd, fmt); 614 + if (ret) 615 + return ret; 616 + 617 + /* set image format */ 618 + switch (fmt->code) { 619 + case V4L2_MBUS_FMT_UYVY8_2X8: 620 + vs6624_write(sd, VS6624_IMG_FMT0, 0x0); 621 + vs6624_write(sd, VS6624_YUV_SETUP, 0x1); 622 + break; 623 + case V4L2_MBUS_FMT_YUYV8_2X8: 624 + vs6624_write(sd, VS6624_IMG_FMT0, 0x0); 625 + vs6624_write(sd, VS6624_YUV_SETUP, 0x3); 626 + break; 627 + case V4L2_MBUS_FMT_RGB565_2X8_LE: 628 + vs6624_write(sd, VS6624_IMG_FMT0, 0x4); 629 + vs6624_write(sd, VS6624_RGB_SETUP, 0x0); 630 + break; 631 + default: 632 + return -EINVAL; 633 + } 634 + 635 + /* set image size */ 636 + if ((fmt->width == VGA_WIDTH) && (fmt->height == VGA_HEIGHT)) 637 + vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x2); 638 + else if ((fmt->width == QVGA_WIDTH) && (fmt->height == QVGA_HEIGHT)) 639 + vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x4); 640 + else if ((fmt->width == QQVGA_WIDTH) && (fmt->height == QQVGA_HEIGHT)) 641 + vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x6); 642 + else if ((fmt->width == CIF_WIDTH) && (fmt->height == CIF_HEIGHT)) 643 + vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x3); 644 + else if ((fmt->width == QCIF_WIDTH) && (fmt->height == QCIF_HEIGHT)) 645 + vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x5); 646 + else if ((fmt->width == QQCIF_WIDTH) && (fmt->height == QQCIF_HEIGHT)) 647 + vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x7); 648 + else { 649 + vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x8); 650 + vs6624_write(sd, VS6624_MAN_HSIZE0_MSB, fmt->width >> 8); 651 + vs6624_write(sd, VS6624_MAN_HSIZE0_LSB, fmt->width & 0xFF); 652 + vs6624_write(sd, VS6624_MAN_VSIZE0_MSB, fmt->height >> 8); 653 + vs6624_write(sd, VS6624_MAN_VSIZE0_LSB, fmt->height & 0xFF); 654 + vs6624_write(sd, VS6624_CROP_CTRL0, 0x1); 655 + } 656 + 657 + sensor->fmt = *fmt; 658 + 659 + return 0; 660 + } 661 + 662 + static int vs6624_g_mbus_fmt(struct v4l2_subdev *sd, 663 + struct v4l2_mbus_framefmt *fmt) 664 + { 665 + struct vs6624 *sensor = to_vs6624(sd); 666 + 667 + *fmt = sensor->fmt; 668 + return 0; 669 + } 670 + 671 + static int vs6624_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) 672 + { 673 + struct vs6624 *sensor = to_vs6624(sd); 674 + struct v4l2_captureparm *cp = &parms->parm.capture; 675 + 676 + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 677 + return -EINVAL; 678 + 679 + memset(cp, 0, sizeof(*cp)); 680 + cp->capability = V4L2_CAP_TIMEPERFRAME; 681 + cp->timeperframe.numerator = sensor->frame_rate.denominator; 682 + cp->timeperframe.denominator = sensor->frame_rate.numerator; 683 + return 0; 684 + } 685 + 686 + static int vs6624_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) 687 + { 688 + struct vs6624 *sensor = to_vs6624(sd); 689 + struct v4l2_captureparm *cp = &parms->parm.capture; 690 + struct v4l2_fract *tpf = &cp->timeperframe; 691 + 692 + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 693 + return -EINVAL; 694 + if (cp->extendedmode != 0) 695 + return -EINVAL; 696 + 697 + if (tpf->numerator == 0 || tpf->denominator == 0 698 + || (tpf->denominator > tpf->numerator * MAX_FRAME_RATE)) { 699 + /* reset to max frame rate */ 700 + tpf->numerator = 1; 701 + tpf->denominator = MAX_FRAME_RATE; 702 + } 703 + sensor->frame_rate.numerator = tpf->denominator; 704 + sensor->frame_rate.denominator = tpf->numerator; 705 + vs6624_write(sd, VS6624_DISABLE_FR_DAMPER, 0x0); 706 + vs6624_write(sd, VS6624_FR_NUM_MSB, 707 + sensor->frame_rate.numerator >> 8); 708 + vs6624_write(sd, VS6624_FR_NUM_LSB, 709 + sensor->frame_rate.numerator & 0xFF); 710 + vs6624_write(sd, VS6624_FR_DEN, 711 + sensor->frame_rate.denominator & 0xFF); 712 + return 0; 713 + } 714 + 715 + static int vs6624_s_stream(struct v4l2_subdev *sd, int enable) 716 + { 717 + if (enable) 718 + vs6624_write(sd, VS6624_USER_CMD, 0x2); 719 + else 720 + vs6624_write(sd, VS6624_USER_CMD, 0x4); 721 + udelay(100); 722 + return 0; 723 + } 724 + 725 + static int vs6624_g_chip_ident(struct v4l2_subdev *sd, 726 + struct v4l2_dbg_chip_ident *chip) 727 + { 728 + int rev; 729 + struct i2c_client *client = v4l2_get_subdevdata(sd); 730 + 731 + rev = (vs6624_read(sd, VS6624_FW_VSN_MAJOR) << 8) 732 + | vs6624_read(sd, VS6624_FW_VSN_MINOR); 733 + 734 + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VS6624, rev); 735 + } 736 + 737 + #ifdef CONFIG_VIDEO_ADV_DEBUG 738 + static int vs6624_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) 739 + { 740 + struct i2c_client *client = v4l2_get_subdevdata(sd); 741 + 742 + if (!v4l2_chip_match_i2c_client(client, &reg->match)) 743 + return -EINVAL; 744 + if (!capable(CAP_SYS_ADMIN)) 745 + return -EPERM; 746 + reg->val = vs6624_read(sd, reg->reg & 0xffff); 747 + reg->size = 1; 748 + return 0; 749 + } 750 + 751 + static int vs6624_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) 752 + { 753 + struct i2c_client *client = v4l2_get_subdevdata(sd); 754 + 755 + if (!v4l2_chip_match_i2c_client(client, &reg->match)) 756 + return -EINVAL; 757 + if (!capable(CAP_SYS_ADMIN)) 758 + return -EPERM; 759 + vs6624_write(sd, reg->reg & 0xffff, reg->val & 0xff); 760 + return 0; 761 + } 762 + #endif 763 + 764 + static const struct v4l2_ctrl_ops vs6624_ctrl_ops = { 765 + .s_ctrl = vs6624_s_ctrl, 766 + }; 767 + 768 + static const struct v4l2_subdev_core_ops vs6624_core_ops = { 769 + .g_chip_ident = vs6624_g_chip_ident, 770 + #ifdef CONFIG_VIDEO_ADV_DEBUG 771 + .g_register = vs6624_g_register, 772 + .s_register = vs6624_s_register, 773 + #endif 774 + }; 775 + 776 + static const struct v4l2_subdev_video_ops vs6624_video_ops = { 777 + .enum_mbus_fmt = vs6624_enum_mbus_fmt, 778 + .try_mbus_fmt = vs6624_try_mbus_fmt, 779 + .s_mbus_fmt = vs6624_s_mbus_fmt, 780 + .g_mbus_fmt = vs6624_g_mbus_fmt, 781 + .s_parm = vs6624_s_parm, 782 + .g_parm = vs6624_g_parm, 783 + .s_stream = vs6624_s_stream, 784 + }; 785 + 786 + static const struct v4l2_subdev_ops vs6624_ops = { 787 + .core = &vs6624_core_ops, 788 + .video = &vs6624_video_ops, 789 + }; 790 + 791 + static int __devinit vs6624_probe(struct i2c_client *client, 792 + const struct i2c_device_id *id) 793 + { 794 + struct vs6624 *sensor; 795 + struct v4l2_subdev *sd; 796 + struct v4l2_ctrl_handler *hdl; 797 + const unsigned *ce; 798 + int ret; 799 + 800 + /* Check if the adapter supports the needed features */ 801 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 802 + return -EIO; 803 + 804 + ce = client->dev.platform_data; 805 + if (ce == NULL) 806 + return -EINVAL; 807 + 808 + ret = gpio_request(*ce, "VS6624 Chip Enable"); 809 + if (ret) { 810 + v4l_err(client, "failed to request GPIO %d\n", *ce); 811 + return ret; 812 + } 813 + gpio_direction_output(*ce, 1); 814 + /* wait 100ms before any further i2c writes are performed */ 815 + mdelay(100); 816 + 817 + sensor = kzalloc(sizeof(*sensor), GFP_KERNEL); 818 + if (sensor == NULL) { 819 + gpio_free(*ce); 820 + return -ENOMEM; 821 + } 822 + 823 + sd = &sensor->sd; 824 + v4l2_i2c_subdev_init(sd, client, &vs6624_ops); 825 + 826 + vs6624_writeregs(sd, vs6624_p1); 827 + vs6624_write(sd, VS6624_MICRO_EN, 0x2); 828 + vs6624_write(sd, VS6624_DIO_EN, 0x1); 829 + mdelay(10); 830 + vs6624_writeregs(sd, vs6624_p2); 831 + 832 + vs6624_writeregs(sd, vs6624_default); 833 + vs6624_write(sd, VS6624_HSYNC_SETUP, 0xF); 834 + vs6624_writeregs(sd, vs6624_run_setup); 835 + 836 + /* set frame rate */ 837 + sensor->frame_rate.numerator = MAX_FRAME_RATE; 838 + sensor->frame_rate.denominator = 1; 839 + vs6624_write(sd, VS6624_DISABLE_FR_DAMPER, 0x0); 840 + vs6624_write(sd, VS6624_FR_NUM_MSB, 841 + sensor->frame_rate.numerator >> 8); 842 + vs6624_write(sd, VS6624_FR_NUM_LSB, 843 + sensor->frame_rate.numerator & 0xFF); 844 + vs6624_write(sd, VS6624_FR_DEN, 845 + sensor->frame_rate.denominator & 0xFF); 846 + 847 + sensor->fmt = vs6624_default_fmt; 848 + sensor->ce_pin = *ce; 849 + 850 + v4l_info(client, "chip found @ 0x%02x (%s)\n", 851 + client->addr << 1, client->adapter->name); 852 + 853 + hdl = &sensor->hdl; 854 + v4l2_ctrl_handler_init(hdl, 4); 855 + v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops, 856 + V4L2_CID_CONTRAST, 0, 0xFF, 1, 0x87); 857 + v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops, 858 + V4L2_CID_SATURATION, 0, 0xFF, 1, 0x78); 859 + v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops, 860 + V4L2_CID_HFLIP, 0, 1, 1, 0); 861 + v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops, 862 + V4L2_CID_VFLIP, 0, 1, 1, 0); 863 + /* hook the control handler into the driver */ 864 + sd->ctrl_handler = hdl; 865 + if (hdl->error) { 866 + int err = hdl->error; 867 + 868 + v4l2_ctrl_handler_free(hdl); 869 + kfree(sensor); 870 + gpio_free(*ce); 871 + return err; 872 + } 873 + 874 + /* initialize the hardware to the default control values */ 875 + ret = v4l2_ctrl_handler_setup(hdl); 876 + if (ret) { 877 + v4l2_ctrl_handler_free(hdl); 878 + kfree(sensor); 879 + gpio_free(*ce); 880 + } 881 + return ret; 882 + } 883 + 884 + static int __devexit vs6624_remove(struct i2c_client *client) 885 + { 886 + struct v4l2_subdev *sd = i2c_get_clientdata(client); 887 + struct vs6624 *sensor = to_vs6624(sd); 888 + 889 + v4l2_device_unregister_subdev(sd); 890 + v4l2_ctrl_handler_free(sd->ctrl_handler); 891 + gpio_free(sensor->ce_pin); 892 + kfree(sensor); 893 + return 0; 894 + } 895 + 896 + static const struct i2c_device_id vs6624_id[] = { 897 + {"vs6624", 0}, 898 + {}, 899 + }; 900 + 901 + MODULE_DEVICE_TABLE(i2c, vs6624_id); 902 + 903 + static struct i2c_driver vs6624_driver = { 904 + .driver = { 905 + .owner = THIS_MODULE, 906 + .name = "vs6624", 907 + }, 908 + .probe = vs6624_probe, 909 + .remove = __devexit_p(vs6624_remove), 910 + .id_table = vs6624_id, 911 + }; 912 + 913 + static __init int vs6624_init(void) 914 + { 915 + return i2c_add_driver(&vs6624_driver); 916 + } 917 + 918 + static __exit void vs6624_exit(void) 919 + { 920 + i2c_del_driver(&vs6624_driver); 921 + } 922 + 923 + module_init(vs6624_init); 924 + module_exit(vs6624_exit); 925 + 926 + MODULE_DESCRIPTION("VS6624 sensor driver"); 927 + MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>"); 928 + MODULE_LICENSE("GPL v2");
+337
drivers/media/video/vs6624_regs.h
··· 1 + /* 2 + * vs6624 - ST VS6624 CMOS image sensor registers 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 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 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #ifndef _VS6624_REGS_H_ 21 + #define _VS6624_REGS_H_ 22 + 23 + /* low level control registers */ 24 + #define VS6624_MICRO_EN 0xC003 /* power enable for all MCU clock */ 25 + #define VS6624_DIO_EN 0xC044 /* enable digital I/O */ 26 + /* device parameters */ 27 + #define VS6624_DEV_ID_MSB 0x0001 /* device id MSB */ 28 + #define VS6624_DEV_ID_LSB 0x0002 /* device id LSB */ 29 + #define VS6624_FW_VSN_MAJOR 0x0004 /* firmware version major */ 30 + #define VS6624_FW_VSN_MINOR 0x0006 /* firmware version minor */ 31 + #define VS6624_PATCH_VSN_MAJOR 0x0008 /* patch version major */ 32 + #define VS6624_PATCH_VSN_MINOR 0x000A /* patch version minor */ 33 + /* host interface manager control */ 34 + #define VS6624_USER_CMD 0x0180 /* user level control of operating states */ 35 + /* host interface manager status */ 36 + #define VS6624_STATE 0x0202 /* current state of the mode manager */ 37 + /* run mode control */ 38 + #define VS6624_METER_ON 0x0280 /* if false AE and AWB are disabled */ 39 + /* mode setup */ 40 + #define VS6624_ACTIVE_PIPE_SETUP 0x0302 /* select the active bank for non view live mode */ 41 + #define VS6624_SENSOR_MODE 0x0308 /* select the different sensor mode */ 42 + /* pipe setup bank0 */ 43 + #define VS6624_IMAGE_SIZE0 0x0380 /* required output dimension */ 44 + #define VS6624_MAN_HSIZE0_MSB 0x0383 /* input required manual H size MSB */ 45 + #define VS6624_MAN_HSIZE0_LSB 0x0384 /* input required manual H size LSB */ 46 + #define VS6624_MAN_VSIZE0_MSB 0x0387 /* input required manual V size MSB */ 47 + #define VS6624_MAN_VSIZE0_LSB 0x0388 /* input required manual V size LSB */ 48 + #define VS6624_ZOOM_HSTEP0_MSB 0x038B /* set the zoom H step MSB */ 49 + #define VS6624_ZOOM_HSTEP0_LSB 0x038C /* set the zoom H step LSB */ 50 + #define VS6624_ZOOM_VSTEP0_MSB 0x038F /* set the zoom V step MSB */ 51 + #define VS6624_ZOOM_VSTEP0_LSB 0x0390 /* set the zoom V step LSB */ 52 + #define VS6624_ZOOM_CTRL0 0x0392 /* control zoon in, out and stop */ 53 + #define VS6624_PAN_HSTEP0_MSB 0x0395 /* set the pan H step MSB */ 54 + #define VS6624_PAN_HSTEP0_LSB 0x0396 /* set the pan H step LSB */ 55 + #define VS6624_PAN_VSTEP0_MSB 0x0399 /* set the pan V step MSB */ 56 + #define VS6624_PAN_VSTEP0_LSB 0x039A /* set the pan V step LSB */ 57 + #define VS6624_PAN_CTRL0 0x039C /* control pan operation */ 58 + #define VS6624_CROP_CTRL0 0x039E /* select cropping mode */ 59 + #define VS6624_CROP_HSTART0_MSB 0x03A1 /* set the cropping H start address MSB */ 60 + #define VS6624_CROP_HSTART0_LSB 0x03A2 /* set the cropping H start address LSB */ 61 + #define VS6624_CROP_HSIZE0_MSB 0x03A5 /* set the cropping H size MSB */ 62 + #define VS6624_CROP_HSIZE0_LSB 0x03A6 /* set the cropping H size LSB */ 63 + #define VS6624_CROP_VSTART0_MSB 0x03A9 /* set the cropping V start address MSB */ 64 + #define VS6624_CROP_VSTART0_LSB 0x03AA /* set the cropping V start address LSB */ 65 + #define VS6624_CROP_VSIZE0_MSB 0x03AD /* set the cropping V size MSB */ 66 + #define VS6624_CROP_VSIZE0_LSB 0x03AE /* set the cropping V size LSB */ 67 + #define VS6624_IMG_FMT0 0x03B0 /* select required output image format */ 68 + #define VS6624_BAYER_OUT_ALIGN0 0x03B2 /* set bayer output alignment */ 69 + #define VS6624_CONTRAST0 0x03B4 /* contrast control for output */ 70 + #define VS6624_SATURATION0 0x03B6 /* saturation control for output */ 71 + #define VS6624_GAMMA0 0x03B8 /* gamma settings */ 72 + #define VS6624_HMIRROR0 0x03BA /* horizontal image orientation flip */ 73 + #define VS6624_VFLIP0 0x03BC /* vertical image orientation flip */ 74 + #define VS6624_CHANNEL_ID0 0x03BE /* logical DMA channel number */ 75 + /* pipe setup bank1 */ 76 + #define VS6624_IMAGE_SIZE1 0x0400 /* required output dimension */ 77 + #define VS6624_MAN_HSIZE1_MSB 0x0403 /* input required manual H size MSB */ 78 + #define VS6624_MAN_HSIZE1_LSB 0x0404 /* input required manual H size LSB */ 79 + #define VS6624_MAN_VSIZE1_MSB 0x0407 /* input required manual V size MSB */ 80 + #define VS6624_MAN_VSIZE1_LSB 0x0408 /* input required manual V size LSB */ 81 + #define VS6624_ZOOM_HSTEP1_MSB 0x040B /* set the zoom H step MSB */ 82 + #define VS6624_ZOOM_HSTEP1_LSB 0x040C /* set the zoom H step LSB */ 83 + #define VS6624_ZOOM_VSTEP1_MSB 0x040F /* set the zoom V step MSB */ 84 + #define VS6624_ZOOM_VSTEP1_LSB 0x0410 /* set the zoom V step LSB */ 85 + #define VS6624_ZOOM_CTRL1 0x0412 /* control zoon in, out and stop */ 86 + #define VS6624_PAN_HSTEP1_MSB 0x0415 /* set the pan H step MSB */ 87 + #define VS6624_PAN_HSTEP1_LSB 0x0416 /* set the pan H step LSB */ 88 + #define VS6624_PAN_VSTEP1_MSB 0x0419 /* set the pan V step MSB */ 89 + #define VS6624_PAN_VSTEP1_LSB 0x041A /* set the pan V step LSB */ 90 + #define VS6624_PAN_CTRL1 0x041C /* control pan operation */ 91 + #define VS6624_CROP_CTRL1 0x041E /* select cropping mode */ 92 + #define VS6624_CROP_HSTART1_MSB 0x0421 /* set the cropping H start address MSB */ 93 + #define VS6624_CROP_HSTART1_LSB 0x0422 /* set the cropping H start address LSB */ 94 + #define VS6624_CROP_HSIZE1_MSB 0x0425 /* set the cropping H size MSB */ 95 + #define VS6624_CROP_HSIZE1_LSB 0x0426 /* set the cropping H size LSB */ 96 + #define VS6624_CROP_VSTART1_MSB 0x0429 /* set the cropping V start address MSB */ 97 + #define VS6624_CROP_VSTART1_LSB 0x042A /* set the cropping V start address LSB */ 98 + #define VS6624_CROP_VSIZE1_MSB 0x042D /* set the cropping V size MSB */ 99 + #define VS6624_CROP_VSIZE1_LSB 0x042E /* set the cropping V size LSB */ 100 + #define VS6624_IMG_FMT1 0x0430 /* select required output image format */ 101 + #define VS6624_BAYER_OUT_ALIGN1 0x0432 /* set bayer output alignment */ 102 + #define VS6624_CONTRAST1 0x0434 /* contrast control for output */ 103 + #define VS6624_SATURATION1 0x0436 /* saturation control for output */ 104 + #define VS6624_GAMMA1 0x0438 /* gamma settings */ 105 + #define VS6624_HMIRROR1 0x043A /* horizontal image orientation flip */ 106 + #define VS6624_VFLIP1 0x043C /* vertical image orientation flip */ 107 + #define VS6624_CHANNEL_ID1 0x043E /* logical DMA channel number */ 108 + /* view live control */ 109 + #define VS6624_VIEW_LIVE_EN 0x0480 /* enable view live mode */ 110 + #define VS6624_INIT_PIPE_SETUP 0x0482 /* select initial pipe setup bank */ 111 + /* view live status */ 112 + #define VS6624_CUR_PIPE_SETUP 0x0500 /* indicates most recently applied setup bank */ 113 + /* power management */ 114 + #define VS6624_TIME_TO_POWER_DOWN 0x0580 /* automatically transition time to stop mode */ 115 + /* video timing parameter host inputs */ 116 + #define VS6624_EXT_CLK_FREQ_NUM_MSB 0x0605 /* external clock frequency numerator MSB */ 117 + #define VS6624_EXT_CLK_FREQ_NUM_LSB 0x0606 /* external clock frequency numerator LSB */ 118 + #define VS6624_EXT_CLK_FREQ_DEN 0x0608 /* external clock frequency denominator */ 119 + /* video timing control */ 120 + #define VS6624_SYS_CLK_MODE 0x0880 /* decides system clock frequency */ 121 + /* frame dimension parameter host inputs */ 122 + #define VS6624_LIGHT_FREQ 0x0C80 /* AC frequency used for flicker free time */ 123 + #define VS6624_FLICKER_COMPAT 0x0C82 /* flicker compatible frame length */ 124 + /* static frame rate control */ 125 + #define VS6624_FR_NUM_MSB 0x0D81 /* desired frame rate numerator MSB */ 126 + #define VS6624_FR_NUM_LSB 0x0D82 /* desired frame rate numerator LSB */ 127 + #define VS6624_FR_DEN 0x0D84 /* desired frame rate denominator */ 128 + /* automatic frame rate control */ 129 + #define VS6624_DISABLE_FR_DAMPER 0x0E80 /* defines frame rate mode */ 130 + #define VS6624_MIN_DAMPER_OUT_MSB 0x0E8C /* minimum frame rate MSB */ 131 + #define VS6624_MIN_DAMPER_OUT_LSB 0x0E8A /* minimum frame rate LSB */ 132 + /* exposure controls */ 133 + #define VS6624_EXPO_MODE 0x1180 /* exposure mode */ 134 + #define VS6624_EXPO_METER 0x1182 /* weights to be associated with the zones */ 135 + #define VS6624_EXPO_TIME_NUM 0x1184 /* exposure time numerator */ 136 + #define VS6624_EXPO_TIME_DEN 0x1186 /* exposure time denominator */ 137 + #define VS6624_EXPO_TIME_MSB 0x1189 /* exposure time for the Manual Mode MSB */ 138 + #define VS6624_EXPO_TIME_LSB 0x118A /* exposure time for the Manual Mode LSB */ 139 + #define VS6624_EXPO_COMPENSATION 0x1190 /* exposure compensation */ 140 + #define VS6624_DIRECT_COARSE_MSB 0x1195 /* coarse integration lines for Direct Mode MSB */ 141 + #define VS6624_DIRECT_COARSE_LSB 0x1196 /* coarse integration lines for Direct Mode LSB */ 142 + #define VS6624_DIRECT_FINE_MSB 0x1199 /* fine integration pixels for Direct Mode MSB */ 143 + #define VS6624_DIRECT_FINE_LSB 0x119A /* fine integration pixels for Direct Mode LSB */ 144 + #define VS6624_DIRECT_ANAL_GAIN_MSB 0x119D /* analog gain for Direct Mode MSB */ 145 + #define VS6624_DIRECT_ANAL_GAIN_LSB 0x119E /* analog gain for Direct Mode LSB */ 146 + #define VS6624_DIRECT_DIGI_GAIN_MSB 0x11A1 /* digital gain for Direct Mode MSB */ 147 + #define VS6624_DIRECT_DIGI_GAIN_LSB 0x11A2 /* digital gain for Direct Mode LSB */ 148 + #define VS6624_FLASH_COARSE_MSB 0x11A5 /* coarse integration lines for Flash Gun Mode MSB */ 149 + #define VS6624_FLASH_COARSE_LSB 0x11A6 /* coarse integration lines for Flash Gun Mode LSB */ 150 + #define VS6624_FLASH_FINE_MSB 0x11A9 /* fine integration pixels for Flash Gun Mode MSB */ 151 + #define VS6624_FLASH_FINE_LSB 0x11AA /* fine integration pixels for Flash Gun Mode LSB */ 152 + #define VS6624_FLASH_ANAL_GAIN_MSB 0x11AD /* analog gain for Flash Gun Mode MSB */ 153 + #define VS6624_FLASH_ANAL_GAIN_LSB 0x11AE /* analog gain for Flash Gun Mode LSB */ 154 + #define VS6624_FLASH_DIGI_GAIN_MSB 0x11B1 /* digital gain for Flash Gun Mode MSB */ 155 + #define VS6624_FLASH_DIGI_GAIN_LSB 0x11B2 /* digital gain for Flash Gun Mode LSB */ 156 + #define VS6624_FREEZE_AE 0x11B4 /* freeze auto exposure */ 157 + #define VS6624_MAX_INT_TIME_MSB 0x11B7 /* user maximum integration time MSB */ 158 + #define VS6624_MAX_INT_TIME_LSB 0x11B8 /* user maximum integration time LSB */ 159 + #define VS6624_FLASH_AG_THR_MSB 0x11BB /* recommend flash gun analog gain threshold MSB */ 160 + #define VS6624_FLASH_AG_THR_LSB 0x11BC /* recommend flash gun analog gain threshold LSB */ 161 + #define VS6624_ANTI_FLICKER_MODE 0x11C0 /* anti flicker mode */ 162 + /* white balance control */ 163 + #define VS6624_WB_MODE 0x1480 /* set white balance mode */ 164 + #define VS6624_MAN_RG 0x1482 /* user setting for red channel gain */ 165 + #define VS6624_MAN_GG 0x1484 /* user setting for green channel gain */ 166 + #define VS6624_MAN_BG 0x1486 /* user setting for blue channel gain */ 167 + #define VS6624_FLASH_RG_MSB 0x148B /* red gain for Flash Gun MSB */ 168 + #define VS6624_FLASH_RG_LSB 0x148C /* red gain for Flash Gun LSB */ 169 + #define VS6624_FLASH_GG_MSB 0x148F /* green gain for Flash Gun MSB */ 170 + #define VS6624_FLASH_GG_LSB 0x1490 /* green gain for Flash Gun LSB */ 171 + #define VS6624_FLASH_BG_MSB 0x1493 /* blue gain for Flash Gun MSB */ 172 + #define VS6624_FLASH_BG_LSB 0x1494 /* blue gain for Flash Gun LSB */ 173 + /* sensor setup */ 174 + #define VS6624_BC_OFFSET 0x1990 /* Black Correction Offset */ 175 + /* image stability */ 176 + #define VS6624_STABLE_WB 0x1900 /* white balance stable */ 177 + #define VS6624_STABLE_EXPO 0x1902 /* exposure stable */ 178 + #define VS6624_STABLE 0x1906 /* system stable */ 179 + /* flash control */ 180 + #define VS6624_FLASH_MODE 0x1A80 /* flash mode */ 181 + #define VS6624_FLASH_OFF_LINE_MSB 0x1A83 /* off line at flash pulse mode MSB */ 182 + #define VS6624_FLASH_OFF_LINE_LSB 0x1A84 /* off line at flash pulse mode LSB */ 183 + /* flash status */ 184 + #define VS6624_FLASH_RECOM 0x1B00 /* flash gun is recommended */ 185 + #define VS6624_FLASH_GRAB_COMPLETE 0x1B02 /* flash gun image has been grabbed */ 186 + /* scythe filter controls */ 187 + #define VS6624_SCYTHE_FILTER 0x1D80 /* disable scythe defect correction */ 188 + /* jack filter controls */ 189 + #define VS6624_JACK_FILTER 0x1E00 /* disable jack defect correction */ 190 + /* demosaic control */ 191 + #define VS6624_ANTI_ALIAS_FILTER 0x1E80 /* anti alias filter suppress */ 192 + /* color matrix dampers */ 193 + #define VS6624_CM_DISABLE 0x1F00 /* disable color matrix damper */ 194 + #define VS6624_CM_LOW_THR_MSB 0x1F03 /* low threshold for exposure MSB */ 195 + #define VS6624_CM_LOW_THR_LSB 0x1F04 /* low threshold for exposure LSB */ 196 + #define VS6624_CM_HIGH_THR_MSB 0x1F07 /* high threshold for exposure MSB */ 197 + #define VS6624_CM_HIGH_THR_LSB 0x1F08 /* high threshold for exposure LSB */ 198 + #define VS6624_CM_MIN_OUT_MSB 0x1F0B /* minimum possible damper output MSB */ 199 + #define VS6624_CM_MIN_OUT_LSB 0x1F0C /* minimum possible damper output LSB */ 200 + /* peaking control */ 201 + #define VS6624_PEAK_GAIN 0x2000 /* controls peaking gain */ 202 + #define VS6624_PEAK_G_DISABLE 0x2002 /* disable peak gain damping */ 203 + #define VS6624_PEAK_LOW_THR_G_MSB 0x2005 /* low threshold for exposure for gain MSB */ 204 + #define VS6624_PEAK_LOW_THR_G_LSB 0x2006 /* low threshold for exposure for gain LSB */ 205 + #define VS6624_PEAK_HIGH_THR_G_MSB 0x2009 /* high threshold for exposure for gain MSB */ 206 + #define VS6624_PEAK_HIGH_THR_G_LSB 0x200A /* high threshold for exposure for gain LSB */ 207 + #define VS6624_PEAK_MIN_OUT_G_MSB 0x200D /* minimum damper output for gain MSB */ 208 + #define VS6624_PEAK_MIN_OUT_G_LSB 0x200E /* minimum damper output for gain LSB */ 209 + #define VS6624_PEAK_LOW_THR 0x2010 /* adjust degree of coring */ 210 + #define VS6624_PEAK_C_DISABLE 0x2012 /* disable coring damping */ 211 + #define VS6624_PEAK_HIGH_THR 0x2014 /* adjust maximum gain */ 212 + #define VS6624_PEAK_LOW_THR_C_MSB 0x2017 /* low threshold for exposure for coring MSB */ 213 + #define VS6624_PEAK_LOW_THR_C_LSB 0x2018 /* low threshold for exposure for coring LSB */ 214 + #define VS6624_PEAK_HIGH_THR_C_MSB 0x201B /* high threshold for exposure for coring MSB */ 215 + #define VS6624_PEAK_HIGH_THR_C_LSB 0x201C /* high threshold for exposure for coring LSB */ 216 + #define VS6624_PEAK_MIN_OUT_C_MSB 0x201F /* minimum damper output for coring MSB */ 217 + #define VS6624_PEAK_MIN_OUT_C_LSB 0x2020 /* minimum damper output for coring LSB */ 218 + /* pipe 0 RGB to YUV matrix manual control */ 219 + #define VS6624_RYM0_MAN_CTRL 0x2180 /* enable manual RGB to YUV matrix */ 220 + #define VS6624_RYM0_W00_MSB 0x2183 /* row 0 column 0 of YUV matrix MSB */ 221 + #define VS6624_RYM0_W00_LSB 0x2184 /* row 0 column 0 of YUV matrix LSB */ 222 + #define VS6624_RYM0_W01_MSB 0x2187 /* row 0 column 1 of YUV matrix MSB */ 223 + #define VS6624_RYM0_W01_LSB 0x2188 /* row 0 column 1 of YUV matrix LSB */ 224 + #define VS6624_RYM0_W02_MSB 0x218C /* row 0 column 2 of YUV matrix MSB */ 225 + #define VS6624_RYM0_W02_LSB 0x218D /* row 0 column 2 of YUV matrix LSB */ 226 + #define VS6624_RYM0_W10_MSB 0x2190 /* row 1 column 0 of YUV matrix MSB */ 227 + #define VS6624_RYM0_W10_LSB 0x218F /* row 1 column 0 of YUV matrix LSB */ 228 + #define VS6624_RYM0_W11_MSB 0x2193 /* row 1 column 1 of YUV matrix MSB */ 229 + #define VS6624_RYM0_W11_LSB 0x2194 /* row 1 column 1 of YUV matrix LSB */ 230 + #define VS6624_RYM0_W12_MSB 0x2197 /* row 1 column 2 of YUV matrix MSB */ 231 + #define VS6624_RYM0_W12_LSB 0x2198 /* row 1 column 2 of YUV matrix LSB */ 232 + #define VS6624_RYM0_W20_MSB 0x219B /* row 2 column 0 of YUV matrix MSB */ 233 + #define VS6624_RYM0_W20_LSB 0x219C /* row 2 column 0 of YUV matrix LSB */ 234 + #define VS6624_RYM0_W21_MSB 0x21A0 /* row 2 column 1 of YUV matrix MSB */ 235 + #define VS6624_RYM0_W21_LSB 0x219F /* row 2 column 1 of YUV matrix LSB */ 236 + #define VS6624_RYM0_W22_MSB 0x21A3 /* row 2 column 2 of YUV matrix MSB */ 237 + #define VS6624_RYM0_W22_LSB 0x21A4 /* row 2 column 2 of YUV matrix LSB */ 238 + #define VS6624_RYM0_YINY_MSB 0x21A7 /* Y in Y MSB */ 239 + #define VS6624_RYM0_YINY_LSB 0x21A8 /* Y in Y LSB */ 240 + #define VS6624_RYM0_YINCB_MSB 0x21AB /* Y in Cb MSB */ 241 + #define VS6624_RYM0_YINCB_LSB 0x21AC /* Y in Cb LSB */ 242 + #define VS6624_RYM0_YINCR_MSB 0x21B0 /* Y in Cr MSB */ 243 + #define VS6624_RYM0_YINCR_LSB 0x21AF /* Y in Cr LSB */ 244 + /* pipe 1 RGB to YUV matrix manual control */ 245 + #define VS6624_RYM1_MAN_CTRL 0x2200 /* enable manual RGB to YUV matrix */ 246 + #define VS6624_RYM1_W00_MSB 0x2203 /* row 0 column 0 of YUV matrix MSB */ 247 + #define VS6624_RYM1_W00_LSB 0x2204 /* row 0 column 0 of YUV matrix LSB */ 248 + #define VS6624_RYM1_W01_MSB 0x2207 /* row 0 column 1 of YUV matrix MSB */ 249 + #define VS6624_RYM1_W01_LSB 0x2208 /* row 0 column 1 of YUV matrix LSB */ 250 + #define VS6624_RYM1_W02_MSB 0x220C /* row 0 column 2 of YUV matrix MSB */ 251 + #define VS6624_RYM1_W02_LSB 0x220D /* row 0 column 2 of YUV matrix LSB */ 252 + #define VS6624_RYM1_W10_MSB 0x2210 /* row 1 column 0 of YUV matrix MSB */ 253 + #define VS6624_RYM1_W10_LSB 0x220F /* row 1 column 0 of YUV matrix LSB */ 254 + #define VS6624_RYM1_W11_MSB 0x2213 /* row 1 column 1 of YUV matrix MSB */ 255 + #define VS6624_RYM1_W11_LSB 0x2214 /* row 1 column 1 of YUV matrix LSB */ 256 + #define VS6624_RYM1_W12_MSB 0x2217 /* row 1 column 2 of YUV matrix MSB */ 257 + #define VS6624_RYM1_W12_LSB 0x2218 /* row 1 column 2 of YUV matrix LSB */ 258 + #define VS6624_RYM1_W20_MSB 0x221B /* row 2 column 0 of YUV matrix MSB */ 259 + #define VS6624_RYM1_W20_LSB 0x221C /* row 2 column 0 of YUV matrix LSB */ 260 + #define VS6624_RYM1_W21_MSB 0x2220 /* row 2 column 1 of YUV matrix MSB */ 261 + #define VS6624_RYM1_W21_LSB 0x221F /* row 2 column 1 of YUV matrix LSB */ 262 + #define VS6624_RYM1_W22_MSB 0x2223 /* row 2 column 2 of YUV matrix MSB */ 263 + #define VS6624_RYM1_W22_LSB 0x2224 /* row 2 column 2 of YUV matrix LSB */ 264 + #define VS6624_RYM1_YINY_MSB 0x2227 /* Y in Y MSB */ 265 + #define VS6624_RYM1_YINY_LSB 0x2228 /* Y in Y LSB */ 266 + #define VS6624_RYM1_YINCB_MSB 0x222B /* Y in Cb MSB */ 267 + #define VS6624_RYM1_YINCB_LSB 0x222C /* Y in Cb LSB */ 268 + #define VS6624_RYM1_YINCR_MSB 0x2220 /* Y in Cr MSB */ 269 + #define VS6624_RYM1_YINCR_LSB 0x222F /* Y in Cr LSB */ 270 + /* pipe 0 gamma manual control */ 271 + #define VS6624_GAMMA_MAN_CTRL0 0x2280 /* enable manual gamma setup */ 272 + #define VS6624_GAMMA_PEAK_R0 0x2282 /* peaked red channel gamma value */ 273 + #define VS6624_GAMMA_PEAK_G0 0x2284 /* peaked green channel gamma value */ 274 + #define VS6624_GAMMA_PEAK_B0 0x2286 /* peaked blue channel gamma value */ 275 + #define VS6624_GAMMA_UNPEAK_R0 0x2288 /* unpeaked red channel gamma value */ 276 + #define VS6624_GAMMA_UNPEAK_G0 0x228A /* unpeaked green channel gamma value */ 277 + #define VS6624_GAMMA_UNPEAK_B0 0x228C /* unpeaked blue channel gamma value */ 278 + /* pipe 1 gamma manual control */ 279 + #define VS6624_GAMMA_MAN_CTRL1 0x2300 /* enable manual gamma setup */ 280 + #define VS6624_GAMMA_PEAK_R1 0x2302 /* peaked red channel gamma value */ 281 + #define VS6624_GAMMA_PEAK_G1 0x2304 /* peaked green channel gamma value */ 282 + #define VS6624_GAMMA_PEAK_B1 0x2306 /* peaked blue channel gamma value */ 283 + #define VS6624_GAMMA_UNPEAK_R1 0x2308 /* unpeaked red channel gamma value */ 284 + #define VS6624_GAMMA_UNPEAK_G1 0x230A /* unpeaked green channel gamma value */ 285 + #define VS6624_GAMMA_UNPEAK_B1 0x230C /* unpeaked blue channel gamma value */ 286 + /* fade to black */ 287 + #define VS6624_F2B_DISABLE 0x2480 /* disable fade to black */ 288 + #define VS6624_F2B_BLACK_VAL_MSB 0x2483 /* black value MSB */ 289 + #define VS6624_F2B_BLACK_VAL_LSB 0x2484 /* black value LSB */ 290 + #define VS6624_F2B_LOW_THR_MSB 0x2487 /* low threshold for exposure MSB */ 291 + #define VS6624_F2B_LOW_THR_LSB 0x2488 /* low threshold for exposure LSB */ 292 + #define VS6624_F2B_HIGH_THR_MSB 0x248B /* high threshold for exposure MSB */ 293 + #define VS6624_F2B_HIGH_THR_LSB 0x248C /* high threshold for exposure LSB */ 294 + #define VS6624_F2B_MIN_OUT_MSB 0x248F /* minimum damper output MSB */ 295 + #define VS6624_F2B_MIN_OUT_LSB 0x2490 /* minimum damper output LSB */ 296 + /* output formatter control */ 297 + #define VS6624_CODE_CK_EN 0x2580 /* code check enable */ 298 + #define VS6624_BLANK_FMT 0x2582 /* blank format */ 299 + #define VS6624_SYNC_CODE_SETUP 0x2584 /* sync code setup */ 300 + #define VS6624_HSYNC_SETUP 0x2586 /* H sync setup */ 301 + #define VS6624_VSYNC_SETUP 0x2588 /* V sync setup */ 302 + #define VS6624_PCLK_SETUP 0x258A /* PCLK setup */ 303 + #define VS6624_PCLK_EN 0x258C /* PCLK enable */ 304 + #define VS6624_OPF_SP_SETUP 0x258E /* output formatter sp setup */ 305 + #define VS6624_BLANK_DATA_MSB 0x2590 /* blank data MSB */ 306 + #define VS6624_BLANK_DATA_LSB 0x2592 /* blank data LSB */ 307 + #define VS6624_RGB_SETUP 0x2594 /* RGB setup */ 308 + #define VS6624_YUV_SETUP 0x2596 /* YUV setup */ 309 + #define VS6624_VSYNC_RIS_COARSE_H 0x2598 /* V sync rising coarse high */ 310 + #define VS6624_VSYNC_RIS_COARSE_L 0x259A /* V sync rising coarse low */ 311 + #define VS6624_VSYNC_RIS_FINE_H 0x259C /* V sync rising fine high */ 312 + #define VS6624_VSYNC_RIS_FINE_L 0x259E /* V sync rising fine low */ 313 + #define VS6624_VSYNC_FALL_COARSE_H 0x25A0 /* V sync falling coarse high */ 314 + #define VS6624_VSYNC_FALL_COARSE_L 0x25A2 /* V sync falling coarse low */ 315 + #define VS6624_VSYNC_FALL_FINE_H 0x25A4 /* V sync falling fine high */ 316 + #define VS6624_VSYNC_FALL_FINE_L 0x25A6 /* V sync falling fine low */ 317 + #define VS6624_HSYNC_RIS_H 0x25A8 /* H sync rising high */ 318 + #define VS6624_HSYNC_RIS_L 0x25AA /* H sync rising low */ 319 + #define VS6624_HSYNC_FALL_H 0x25AC /* H sync falling high */ 320 + #define VS6624_HSYNC_FALL_L 0x25AE /* H sync falling low */ 321 + #define VS6624_OUT_IF 0x25B0 /* output interface */ 322 + #define VS6624_CCP_EXT_DATA 0x25B2 /* CCP extra data */ 323 + /* NoRA controls */ 324 + #define VS6624_NORA_DISABLE 0x2600 /* NoRA control mode */ 325 + #define VS6624_NORA_USAGE 0x2602 /* usage */ 326 + #define VS6624_NORA_SPLIT_KN 0x2604 /* split kn */ 327 + #define VS6624_NORA_SPLIT_NI 0x2606 /* split ni */ 328 + #define VS6624_NORA_TIGHT_G 0x2608 /* tight green */ 329 + #define VS6624_NORA_DISABLE_NP 0x260A /* disable noro promoting */ 330 + #define VS6624_NORA_LOW_THR_MSB 0x260D /* low threshold for exposure MSB */ 331 + #define VS6624_NORA_LOW_THR_LSB 0x260E /* low threshold for exposure LSB */ 332 + #define VS6624_NORA_HIGH_THR_MSB 0x2611 /* high threshold for exposure MSB */ 333 + #define VS6624_NORA_HIGH_THR_LSB 0x2612 /* high threshold for exposure LSB */ 334 + #define VS6624_NORA_MIN_OUT_MSB 0x2615 /* minimum damper output MSB */ 335 + #define VS6624_NORA_MIN_OUT_LSB 0x2616 /* minimum damper output LSB */ 336 + 337 + #endif
+2 -2
drivers/media/video/w9966.c
··· 129 129 MODULE_VERSION("0.33.1"); 130 130 131 131 #ifdef MODULE 132 - static const char *pardev[] = {[0 ... W9966_MAXCAMS] = ""}; 132 + static char *pardev[] = {[0 ... W9966_MAXCAMS] = ""}; 133 133 #else 134 - static const char *pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"}; 134 + static char *pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"}; 135 135 #endif 136 136 module_param_array(pardev, charp, NULL, 0); 137 137 MODULE_PARM_DESC(pardev, "pardev: where to search for\n"
+1 -12
drivers/media/video/wm8739.c
··· 291 291 .id_table = wm8739_id, 292 292 }; 293 293 294 - static __init int init_wm8739(void) 295 - { 296 - return i2c_add_driver(&wm8739_driver); 297 - } 298 - 299 - static __exit void exit_wm8739(void) 300 - { 301 - i2c_del_driver(&wm8739_driver); 302 - } 303 - 304 - module_init(init_wm8739); 305 - module_exit(exit_wm8739); 294 + module_i2c_driver(wm8739_driver);
+1 -12
drivers/media/video/wm8775.c
··· 339 339 .id_table = wm8775_id, 340 340 }; 341 341 342 - static __init int init_wm8775(void) 343 - { 344 - return i2c_add_driver(&wm8775_driver); 345 - } 346 - 347 - static __exit void exit_wm8775(void) 348 - { 349 - i2c_del_driver(&wm8775_driver); 350 - } 351 - 352 - module_init(init_wm8775); 353 - module_exit(exit_wm8775); 342 + module_i2c_driver(wm8775_driver);
+1 -1
drivers/staging/media/Kconfig
··· 6 6 don't have the "normal" Linux kernel quality level. 7 7 Most of them don't follow properly the V4L, DVB and/or RC API's, 8 8 so, they won't likely work fine with the existing applications. 9 - That also means that, one fixed, their API's will change to match 9 + That also means that, once fixed, their API's will change to match 10 10 the existing ones. 11 11 12 12 If you wish to work on these drivers, to help improve them, or
+1 -1
drivers/staging/media/as102/as102_drv.c
··· 27 27 #include <linux/uaccess.h> 28 28 #include <linux/usb.h> 29 29 30 - /* header file for Usb device driver*/ 30 + /* header file for usb device driver*/ 31 31 #include "as102_drv.h" 32 32 #include "as102_fw.h" 33 33 #include "dvbdev.h"
+1 -1
drivers/staging/media/as102/as102_drv.h
··· 76 76 struct as10x_bus_adapter_t bus_adap; 77 77 struct list_head device_entry; 78 78 struct kref kref; 79 - unsigned long minor; 79 + uint8_t elna_cfg; 80 80 81 81 struct dvb_adapter dvb_adap; 82 82 struct dvb_frontend dvb_fe;
+3 -3
drivers/staging/media/as102/as102_fe.c
··· 265 265 266 266 if (acquire) { 267 267 if (elna_enable) 268 - as10x_cmd_set_context(&dev->bus_adap, 1010, 0xC0); 268 + as10x_cmd_set_context(&dev->bus_adap, CONTEXT_LNA, dev->elna_cfg); 269 269 270 270 ret = as10x_cmd_turn_on(&dev->bus_adap); 271 271 } else { ··· 337 337 strncpy(dvb_fe->ops.info.name, as102_dev->name, 338 338 sizeof(dvb_fe->ops.info.name)); 339 339 340 - /* register dbvb frontend */ 340 + /* register dvb frontend */ 341 341 errno = dvb_register_frontend(dvb_adap, dvb_fe); 342 342 if (errno == 0) 343 343 dvb_fe->tuner_priv = as102_dev; ··· 349 349 struct as10x_tps *as10x_tps) 350 350 { 351 351 352 - /* extract consteallation */ 352 + /* extract constellation */ 353 353 switch (as10x_tps->modulation) { 354 354 case CONST_QPSK: 355 355 fe_tps->modulation = QPSK;
+1 -1
drivers/staging/media/as102/as102_fw.h
··· 29 29 union { 30 30 unsigned char request[2]; 31 31 unsigned char length[2]; 32 - } u; 32 + } __packed u; 33 33 struct as10x_raw_fw_pkt raw; 34 34 } __packed; 35 35
+16 -1
drivers/staging/media/as102/as102_usb_drv.c
··· 57 57 NULL /* Terminating entry */ 58 58 }; 59 59 60 + /* eLNA configuration: devices built on the reference design work best 61 + with 0xA0, while custom designs seem to require 0xC0 */ 62 + static uint8_t const as102_elna_cfg[] = { 63 + 0xA0, 64 + 0xC0, 65 + 0xC0, 66 + 0xA0, 67 + 0xA0, 68 + 0x00 /* Terminating entry */ 69 + }; 70 + 60 71 struct usb_driver as102_usb_driver = { 61 72 .name = DRIVER_FULL_NAME, 62 73 .probe = as102_usb_probe, ··· 281 270 } 282 271 283 272 urb->transfer_buffer = dev->stream + (i * AS102_USB_BUF_SIZE); 273 + urb->transfer_dma = dev->dma_addr + (i * AS102_USB_BUF_SIZE); 274 + urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; 284 275 urb->transfer_buffer_length = AS102_USB_BUF_SIZE; 285 276 286 277 dev->stream_urb[i] = urb; ··· 382 369 /* Assign the user-friendly device name */ 383 370 for (i = 0; i < (sizeof(as102_usb_id_table) / 384 371 sizeof(struct usb_device_id)); i++) { 385 - if (id == &as102_usb_id_table[i]) 372 + if (id == &as102_usb_id_table[i]) { 386 373 as102_dev->name = as102_device_names[i]; 374 + as102_dev->elna_cfg = as102_elna_cfg[i]; 375 + } 387 376 } 388 377 389 378 if (as102_dev->name == NULL)
+40 -40
drivers/staging/media/as102/as10x_cmd.h
··· 99 99 struct { 100 100 /* request identifier */ 101 101 uint16_t proc_id; 102 - } req; 102 + } __packed req; 103 103 /* response */ 104 104 struct { 105 105 /* response identifier */ 106 106 uint16_t proc_id; 107 107 /* error */ 108 108 uint8_t error; 109 - } rsp; 109 + } __packed rsp; 110 110 } __packed; 111 111 112 112 union as10x_turn_off { ··· 114 114 struct { 115 115 /* request identifier */ 116 116 uint16_t proc_id; 117 - } req; 117 + } __packed req; 118 118 /* response */ 119 119 struct { 120 120 /* response identifier */ 121 121 uint16_t proc_id; 122 122 /* error */ 123 123 uint8_t err; 124 - } rsp; 124 + } __packed rsp; 125 125 } __packed; 126 126 127 127 union as10x_set_tune { ··· 131 131 uint16_t proc_id; 132 132 /* tune params */ 133 133 struct as10x_tune_args args; 134 - } req; 134 + } __packed req; 135 135 /* response */ 136 136 struct { 137 137 /* response identifier */ 138 138 uint16_t proc_id; 139 139 /* response error */ 140 140 uint8_t error; 141 - } rsp; 141 + } __packed rsp; 142 142 } __packed; 143 143 144 144 union as10x_get_tune_status { ··· 146 146 struct { 147 147 /* request identifier */ 148 148 uint16_t proc_id; 149 - } req; 149 + } __packed req; 150 150 /* response */ 151 151 struct { 152 152 /* response identifier */ ··· 155 155 uint8_t error; 156 156 /* tune status */ 157 157 struct as10x_tune_status sts; 158 - } rsp; 158 + } __packed rsp; 159 159 } __packed; 160 160 161 161 union as10x_get_tps { ··· 163 163 struct { 164 164 /* request identifier */ 165 165 uint16_t proc_id; 166 - } req; 166 + } __packed req; 167 167 /* response */ 168 168 struct { 169 169 /* response identifier */ ··· 172 172 uint8_t error; 173 173 /* tps details */ 174 174 struct as10x_tps tps; 175 - } rsp; 175 + } __packed rsp; 176 176 } __packed; 177 177 178 178 union as10x_common { ··· 180 180 struct { 181 181 /* request identifier */ 182 182 uint16_t proc_id; 183 - } req; 183 + } __packed req; 184 184 /* response */ 185 185 struct { 186 186 /* response identifier */ 187 187 uint16_t proc_id; 188 188 /* response error */ 189 189 uint8_t error; 190 - } rsp; 190 + } __packed rsp; 191 191 } __packed; 192 192 193 193 union as10x_add_pid_filter { ··· 201 201 uint8_t stream_type; 202 202 /* PID index in filter table */ 203 203 uint8_t idx; 204 - } req; 204 + } __packed req; 205 205 /* response */ 206 206 struct { 207 207 /* response identifier */ ··· 210 210 uint8_t error; 211 211 /* Filter id */ 212 212 uint8_t filter_id; 213 - } rsp; 213 + } __packed rsp; 214 214 } __packed; 215 215 216 216 union as10x_del_pid_filter { ··· 220 220 uint16_t proc_id; 221 221 /* PID to remove */ 222 222 uint16_t pid; 223 - } req; 223 + } __packed req; 224 224 /* response */ 225 225 struct { 226 226 /* response identifier */ 227 227 uint16_t proc_id; 228 228 /* response error */ 229 229 uint8_t error; 230 - } rsp; 230 + } __packed rsp; 231 231 } __packed; 232 232 233 233 union as10x_start_streaming { ··· 235 235 struct { 236 236 /* request identifier */ 237 237 uint16_t proc_id; 238 - } req; 238 + } __packed req; 239 239 /* response */ 240 240 struct { 241 241 /* response identifier */ 242 242 uint16_t proc_id; 243 243 /* error */ 244 244 uint8_t error; 245 - } rsp; 245 + } __packed rsp; 246 246 } __packed; 247 247 248 248 union as10x_stop_streaming { ··· 250 250 struct { 251 251 /* request identifier */ 252 252 uint16_t proc_id; 253 - } req; 253 + } __packed req; 254 254 /* response */ 255 255 struct { 256 256 /* response identifier */ 257 257 uint16_t proc_id; 258 258 /* error */ 259 259 uint8_t error; 260 - } rsp; 260 + } __packed rsp; 261 261 } __packed; 262 262 263 263 union as10x_get_demod_stats { ··· 265 265 struct { 266 266 /* request identifier */ 267 267 uint16_t proc_id; 268 - } req; 268 + } __packed req; 269 269 /* response */ 270 270 struct { 271 271 /* response identifier */ ··· 274 274 uint8_t error; 275 275 /* demod stats */ 276 276 struct as10x_demod_stats stats; 277 - } rsp; 277 + } __packed rsp; 278 278 } __packed; 279 279 280 280 union as10x_get_impulse_resp { ··· 282 282 struct { 283 283 /* request identifier */ 284 284 uint16_t proc_id; 285 - } req; 285 + } __packed req; 286 286 /* response */ 287 287 struct { 288 288 /* response identifier */ ··· 291 291 uint8_t error; 292 292 /* impulse response ready */ 293 293 uint8_t is_ready; 294 - } rsp; 294 + } __packed rsp; 295 295 } __packed; 296 296 297 297 union as10x_fw_context { ··· 305 305 uint16_t tag; 306 306 /* context request type */ 307 307 uint16_t type; 308 - } req; 308 + } __packed req; 309 309 /* response */ 310 310 struct { 311 311 /* response identifier */ ··· 316 316 uint16_t type; 317 317 /* error */ 318 318 uint8_t error; 319 - } rsp; 319 + } __packed rsp; 320 320 } __packed; 321 321 322 322 union as10x_set_register { ··· 328 328 struct as10x_register_addr reg_addr; 329 329 /* register content */ 330 330 struct as10x_register_value reg_val; 331 - } req; 331 + } __packed req; 332 332 /* response */ 333 333 struct { 334 334 /* response identifier */ 335 335 uint16_t proc_id; 336 336 /* error */ 337 337 uint8_t error; 338 - } rsp; 338 + } __packed rsp; 339 339 } __packed; 340 340 341 341 union as10x_get_register { ··· 345 345 uint16_t proc_id; 346 346 /* register description */ 347 347 struct as10x_register_addr reg_addr; 348 - } req; 348 + } __packed req; 349 349 /* response */ 350 350 struct { 351 351 /* response identifier */ ··· 354 354 uint8_t error; 355 355 /* register content */ 356 356 struct as10x_register_value reg_val; 357 - } rsp; 357 + } __packed rsp; 358 358 } __packed; 359 359 360 360 union as10x_cfg_change_mode { ··· 364 364 uint16_t proc_id; 365 365 /* mode */ 366 366 uint8_t mode; 367 - } req; 367 + } __packed req; 368 368 /* response */ 369 369 struct { 370 370 /* response identifier */ 371 371 uint16_t proc_id; 372 372 /* error */ 373 373 uint8_t error; 374 - } rsp; 374 + } __packed rsp; 375 375 } __packed; 376 376 377 377 struct as10x_cmd_header_t { ··· 394 394 struct as10x_register_addr reg_addr; 395 395 /* nb blocks to read */ 396 396 uint16_t num_blocks; 397 - } req; 397 + } __packed req; 398 398 /* response */ 399 399 struct { 400 400 /* response identifier */ ··· 408 408 uint8_t data8[DUMP_BLOCK_SIZE]; 409 409 uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)]; 410 410 uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)]; 411 - } u; 412 - } rsp; 411 + } __packed u; 412 + } __packed rsp; 413 413 } __packed; 414 414 415 415 union as10x_dumplog_memory { ··· 418 418 uint16_t proc_id; 419 419 /* dump memory type request */ 420 420 uint8_t dump_req; 421 - } req; 421 + } __packed req; 422 422 struct { 423 423 /* request identifier */ 424 424 uint16_t proc_id; ··· 428 428 uint8_t dump_rsp; 429 429 /* dump data */ 430 430 uint8_t data[DUMP_BLOCK_SIZE]; 431 - } rsp; 431 + } __packed rsp; 432 432 } __packed; 433 433 434 434 union as10x_raw_data { ··· 437 437 uint16_t proc_id; 438 438 uint8_t data[64 - sizeof(struct as10x_cmd_header_t) 439 439 - 2 /* proc_id */]; 440 - } req; 440 + } __packed req; 441 441 /* response */ 442 442 struct { 443 443 uint16_t proc_id; 444 444 uint8_t error; 445 445 uint8_t data[64 - sizeof(struct as10x_cmd_header_t) 446 446 - 2 /* proc_id */ - 1 /* rc */]; 447 - } rsp; 447 + } __packed rsp; 448 448 } __packed; 449 449 450 450 struct as10x_cmd_t { ··· 469 469 union as10x_dump_memory dump_memory; 470 470 union as10x_dumplog_memory dumplog_memory; 471 471 union as10x_raw_data raw_data; 472 - } body; 472 + } __packed body; 473 473 } __packed; 474 474 475 475 struct as10x_token_cmd_t {
+1 -1
drivers/staging/media/as102/as10x_types.h
··· 181 181 uint8_t value8; /* 8 bit value */ 182 182 uint16_t value16; /* 16 bit value */ 183 183 uint32_t value32; /* 32 bit value */ 184 - } u; 184 + } __packed u; 185 185 } __packed; 186 186 187 187 struct as10x_register_addr {
+78 -164
drivers/staging/media/easycap/easycap_main.c
··· 2849 2849 .poll = easycap_poll, 2850 2850 .mmap = easycap_mmap, 2851 2851 }; 2852 - /*****************************************************************************/ 2853 - /*---------------------------------------------------------------------------*/ 2852 + 2854 2853 /* 2855 - * WHEN THE EasyCAP IS PHYSICALLY PLUGGED IN, THIS FUNCTION IS CALLED THREE 2856 - * TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE. 2854 + * When the device is plugged, this function is called three times, 2855 + * one for each interface. 2857 2856 */ 2858 - /*---------------------------------------------------------------------------*/ 2859 2857 static int easycap_usb_probe(struct usb_interface *intf, 2860 2858 const struct usb_device_id *id) 2861 2859 { ··· 2882 2884 2883 2885 usbdev = interface_to_usbdev(intf); 2884 2886 2885 - /*---------------------------------------------------------------------------*/ 2886 2887 alt = usb_altnum_to_altsetting(intf, 0); 2887 2888 if (!alt) { 2888 2889 SAY("ERROR: usb_host_interface not found\n"); ··· 2893 2896 SAY("ERROR: intf_descriptor is NULL\n"); 2894 2897 return -EFAULT; 2895 2898 } 2896 - /*---------------------------------------------------------------------------*/ 2897 - /* 2898 - * GET PROPERTIES OF PROBED INTERFACE 2899 - */ 2900 - /*---------------------------------------------------------------------------*/ 2899 + 2900 + /* Get properties of probed interface */ 2901 2901 bInterfaceNumber = interface->bInterfaceNumber; 2902 2902 bInterfaceClass = interface->bInterfaceClass; 2903 2903 bInterfaceSubClass = interface->bInterfaceSubClass; ··· 2906 2912 (long int)(intf->cur_altsetting - intf->altsetting)); 2907 2913 JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n", 2908 2914 bInterfaceNumber, bInterfaceClass, bInterfaceSubClass); 2909 - /*---------------------------------------------------------------------------*/ 2910 - /* 2911 - * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED. 2912 - * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS 2913 - * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE EasyCAP WAS 2914 - * PHYSICALLY UNPLUGGED. 2915 - * 2916 - * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN 2917 - * INTERFACES 1 AND 2 ARE PROBED. 2918 - */ 2919 - /*---------------------------------------------------------------------------*/ 2915 + 2916 + /* 2917 + * A new struct easycap is always allocated when interface 0 is probed. 2918 + * It is not possible here to free any existing struct easycap. 2919 + * This should have been done by easycap_delete() when the device was 2920 + * physically unplugged. 2921 + * The allocated struct easycap is saved for later usage when 2922 + * interfaces 1 and 2 are probed. 2923 + */ 2920 2924 if (0 == bInterfaceNumber) { 2921 2925 peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); 2922 2926 if (!peasycap) { 2923 2927 SAY("ERROR: Could not allocate peasycap\n"); 2924 2928 return -ENOMEM; 2925 2929 } 2926 - /*---------------------------------------------------------------------------*/ 2927 - /* 2928 - * PERFORM URGENT INTIALIZATIONS ... 2929 - */ 2930 - /*---------------------------------------------------------------------------*/ 2930 + 2931 + /* Perform urgent initializations */ 2931 2932 peasycap->minor = -1; 2932 2933 kref_init(&peasycap->kref); 2933 2934 JOM(8, "intf[%i]: after kref_init(..._video) " ··· 2965 2976 2966 2977 peasycap->allocation_video_struct = sizeof(struct easycap); 2967 2978 2968 - /*---------------------------------------------------------------------------*/ 2969 - /* 2970 - * ... AND FURTHER INITIALIZE THE STRUCTURE 2971 - */ 2972 - /*---------------------------------------------------------------------------*/ 2979 + /* and further initialize the structure */ 2973 2980 peasycap->pusb_device = usbdev; 2974 2981 peasycap->pusb_interface = intf; 2975 2982 ··· 2987 3002 2988 3003 peasycap->frame_buffer_many = FRAME_BUFFER_MANY; 2989 3004 2990 - /*---------------------------------------------------------------------------*/ 2991 - /* 2992 - * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ... 2993 - */ 2994 - /*---------------------------------------------------------------------------*/ 3005 + /* Dynamically fill in the available formats */ 2995 3006 rc = easycap_video_fillin_formats(); 2996 3007 if (0 > rc) { 2997 3008 SAM("ERROR: fillin_formats() rc = %i\n", rc); ··· 2995 3014 } 2996 3015 JOM(4, "%i formats available\n", rc); 2997 3016 2998 - /* ... AND POPULATE easycap.inputset[] */ 2999 - 3017 + /* Populate easycap.inputset[] */ 3000 3018 inputset = peasycap->inputset; 3001 - 3002 3019 fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; 3003 3020 m = 0; 3004 3021 mask = 0; ··· 3009 3030 mask = easycap_standard[i].mask; 3010 3031 } 3011 3032 } 3012 - 3013 3033 if (1 != m) { 3014 3034 SAM("ERROR: " 3015 3035 "inputset->standard_offset unpopulated, %i=m\n", m); ··· 3067 3089 JOM(4, "populated inputset[]\n"); 3068 3090 JOM(4, "finished initialization\n"); 3069 3091 } else { 3070 - /*---------------------------------------------------------------------------*/ 3071 - /* 3072 - * FIXME 3073 - * 3074 - * IDENTIFY THE APPROPRIATE POINTER peasycap FOR INTERFACES 1 AND 2. 3075 - * THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE. 3076 - */ 3077 - /*---------------------------------------------------------------------------*/ 3092 + 3093 + /* 3094 + * FIXME: Identify the appropriate pointer 3095 + * peasycap for interfaces 1 and 2. 3096 + * The address of peasycap->pusb_device 3097 + * is reluctantly used for this purpose. 3098 + */ 3078 3099 for (ndong = 0; ndong < DONGLE_MANY; ndong++) { 3079 3100 if (usbdev == easycapdc60_dongle[ndong].peasycap-> 3080 3101 pusb_device) { ··· 3094 3117 return -ENODEV; 3095 3118 } 3096 3119 } 3097 - /*---------------------------------------------------------------------------*/ 3120 + 3098 3121 if ((USB_CLASS_VIDEO == bInterfaceClass) || 3099 3122 (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { 3100 3123 if (-1 == peasycap->video_interface) { ··· 3126 3149 } 3127 3150 } 3128 3151 } 3129 - /*---------------------------------------------------------------------------*/ 3130 - /* 3131 - * INVESTIGATE ALL ALTSETTINGS. 3132 - * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS. 3133 - */ 3134 - /*---------------------------------------------------------------------------*/ 3135 - isokalt = 0; 3136 3152 3153 + /* 3154 + * Investigate all altsettings. This is done in detail 3155 + * because USB device 05e1:0408 has disparate incarnations. 3156 + */ 3157 + isokalt = 0; 3137 3158 for (i = 0; i < intf->num_altsetting; i++) { 3138 3159 alt = usb_altnum_to_altsetting(intf, i); 3139 3160 if (!alt) { ··· 3147 3172 if (0 == interface->bNumEndpoints) 3148 3173 JOM(4, "intf[%i]alt[%i] has no endpoints\n", 3149 3174 bInterfaceNumber, i); 3150 - /*---------------------------------------------------------------------------*/ 3151 3175 for (j = 0; j < interface->bNumEndpoints; j++) { 3152 3176 ep = &alt->endpoint[j].desc; 3153 3177 if (!ep) { ··· 3286 3312 } 3287 3313 } 3288 3314 } 3289 - /*---------------------------------------------------------------------------*/ 3290 - /* 3291 - * PERFORM INITIALIZATION OF THE PROBED INTERFACE 3292 - */ 3293 - /*---------------------------------------------------------------------------*/ 3315 + 3316 + /* Perform initialization of the probed interface */ 3294 3317 JOM(4, "initialization begins for interface %i\n", 3295 3318 interface->bInterfaceNumber); 3296 3319 switch (bInterfaceNumber) { 3297 - /*---------------------------------------------------------------------------*/ 3298 - /* 3299 - * INTERFACE 0 IS THE VIDEO INTERFACE 3300 - */ 3301 - /*---------------------------------------------------------------------------*/ 3320 + /* 0: Video interface */ 3302 3321 case 0: { 3303 3322 if (!peasycap) { 3304 3323 SAM("MISTAKE: peasycap is NULL\n"); ··· 3304 3337 peasycap->video_altsetting_on = okalt[isokalt - 1]; 3305 3338 JOM(4, "%i=video_altsetting_on <====\n", 3306 3339 peasycap->video_altsetting_on); 3307 - /*---------------------------------------------------------------------------*/ 3308 - /* 3309 - * DECIDE THE VIDEO STREAMING PARAMETERS 3310 - */ 3311 - /*---------------------------------------------------------------------------*/ 3340 + 3341 + /* Decide video streaming parameters */ 3312 3342 peasycap->video_endpointnumber = okepn[isokalt - 1]; 3313 3343 JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber); 3314 3344 maxpacketsize = okmps[isokalt - 1]; ··· 3337 3373 SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n"); 3338 3374 return -EFAULT; 3339 3375 } 3340 - /*---------------------------------------------------------------------------*/ 3341 3376 if (-1 == peasycap->video_interface) { 3342 3377 SAM("MISTAKE: video_interface is unset\n"); 3343 3378 return -EFAULT; ··· 3361 3398 SAM("MISTAKE: video_isoc_buffer_size is unset\n"); 3362 3399 return -EFAULT; 3363 3400 } 3364 - /*---------------------------------------------------------------------------*/ 3365 - /* 3366 - * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST. 3367 - */ 3368 - /*---------------------------------------------------------------------------*/ 3401 + 3402 + /* 3403 + * Allocate memory for video buffers. 3404 + * Lists must be initialized first. 3405 + */ 3369 3406 INIT_LIST_HEAD(&(peasycap->urb_video_head)); 3370 3407 peasycap->purb_video_head = &(peasycap->urb_video_head); 3371 - /*---------------------------------------------------------------------------*/ 3372 3408 JOM(4, "allocating %i frame buffers of size %li\n", 3373 3409 FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE); 3374 3410 JOM(4, ".... each scattered over %li pages\n", ··· 3398 3436 peasycap->frame_read = 0; 3399 3437 JOM(4, "allocation of frame buffers done: %i pages\n", k * 3400 3438 m); 3401 - /*---------------------------------------------------------------------------*/ 3402 3439 JOM(4, "allocating %i field buffers of size %li\n", 3403 3440 FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE); 3404 3441 JOM(4, ".... each scattered over %li pages\n", ··· 3429 3468 peasycap->field_read = 0; 3430 3469 JOM(4, "allocation of field buffers done: %i pages\n", k * 3431 3470 m); 3432 - /*---------------------------------------------------------------------------*/ 3433 3471 JOM(4, "allocating %i isoc video buffers of size %i\n", 3434 3472 VIDEO_ISOC_BUFFER_MANY, 3435 3473 peasycap->video_isoc_buffer_size); ··· 3452 3492 } 3453 3493 JOM(4, "allocation of isoc video buffers done: %i pages\n", 3454 3494 k * (0x01 << VIDEO_ISOC_ORDER)); 3455 - /*---------------------------------------------------------------------------*/ 3456 - /* 3457 - * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... 3458 - */ 3459 - /*---------------------------------------------------------------------------*/ 3495 + 3496 + /* Allocate and initialize multiple struct usb */ 3460 3497 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); 3461 3498 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", 3462 3499 peasycap->video_isoc_framesperdesc); ··· 3472 3515 } 3473 3516 3474 3517 peasycap->allocation_video_urb += 1; 3475 - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 3476 3518 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); 3477 3519 if (!pdata_urb) { 3478 3520 SAM("ERROR: Could not allocate struct data_urb.\n"); ··· 3486 3530 pdata_urb->length = 0; 3487 3531 list_add_tail(&(pdata_urb->list_head), 3488 3532 peasycap->purb_video_head); 3489 - /*---------------------------------------------------------------------------*/ 3490 - /* 3491 - * ... AND INITIALIZE THEM 3492 - */ 3493 - /*---------------------------------------------------------------------------*/ 3533 + 3534 + /* Initialize allocated urbs */ 3494 3535 if (!k) { 3495 3536 JOM(4, "initializing video urbs thus:\n"); 3496 3537 JOM(4, " purb->interval = 1;\n"); ··· 3535 3582 } 3536 3583 } 3537 3584 JOM(4, "allocation of %i struct urb done.\n", k); 3538 - /*--------------------------------------------------------------------------*/ 3539 - /* 3540 - * SAVE POINTER peasycap IN THIS INTERFACE. 3541 - */ 3542 - /*--------------------------------------------------------------------------*/ 3585 + 3586 + /* Save pointer peasycap in this interface */ 3543 3587 usb_set_intfdata(intf, peasycap); 3544 - /*---------------------------------------------------------------------------*/ 3545 - /* 3546 - * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER, 3547 - * THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE 3548 - * CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH. 3549 - * BEWARE. 3550 - */ 3551 - /*---------------------------------------------------------------------------*/ 3588 + 3589 + /* 3590 + * It is essential to initialize the hardware before, 3591 + * rather than after, the device is registered, 3592 + * because some udev rules triggers easycap_open() 3593 + * immediately after registration, causing a clash. 3594 + */ 3552 3595 peasycap->ntsc = easycap_ntsc; 3553 3596 JOM(8, "defaulting initially to %s\n", 3554 3597 easycap_ntsc ? "NTSC" : "PAL"); ··· 3553 3604 SAM("ERROR: reset() rc = %i\n", rc); 3554 3605 return -EFAULT; 3555 3606 } 3556 - /*--------------------------------------------------------------------------*/ 3557 - /* 3558 - * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. 3559 - */ 3560 - /*--------------------------------------------------------------------------*/ 3607 + 3608 + /* The video device can now be registered */ 3561 3609 if (v4l2_device_register(&intf->dev, &peasycap->v4l2_device)) { 3562 3610 SAM("v4l2_device_register() failed\n"); 3563 3611 return -ENODEV; 3564 3612 } 3565 3613 JOM(4, "registered device instance: %s\n", 3566 3614 peasycap->v4l2_device.name); 3567 - /*---------------------------------------------------------------------------*/ 3568 - /* 3569 - * FIXME 3570 - * 3571 - * 3572 - * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG: 3573 - */ 3574 - /*---------------------------------------------------------------------------*/ 3615 + 3616 + /* 3617 + * FIXME: This is believed to be harmless, 3618 + * but may well be unnecessary or wrong. 3619 + */ 3575 3620 peasycap->video_device.v4l2_dev = NULL; 3576 - /*---------------------------------------------------------------------------*/ 3577 3621 3578 3622 3579 3623 strcpy(&peasycap->video_device.name[0], "easycapdc60"); ··· 3590 3648 3591 3649 break; 3592 3650 } 3593 - /*--------------------------------------------------------------------------*/ 3594 - /* 3595 - * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE 3596 - * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE 3597 - */ 3598 - /*--------------------------------------------------------------------------*/ 3651 + /* 1: Audio control */ 3599 3652 case 1: { 3600 3653 if (!peasycap) { 3601 3654 SAM("MISTAKE: peasycap is NULL\n"); 3602 3655 return -EFAULT; 3603 3656 } 3604 - /*--------------------------------------------------------------------------*/ 3605 - /* 3606 - * SAVE POINTER peasycap IN INTERFACE 1 3607 - */ 3608 - /*--------------------------------------------------------------------------*/ 3657 + /* Save pointer peasycap in this interface */ 3609 3658 usb_set_intfdata(intf, peasycap); 3610 3659 JOM(4, "no initialization required for interface %i\n", 3611 3660 interface->bInterfaceNumber); 3612 3661 break; 3613 3662 } 3614 - /*--------------------------------------------------------------------------*/ 3663 + /* 2: Audio streaming */ 3615 3664 case 2: { 3616 3665 if (!peasycap) { 3617 3666 SAM("MISTAKE: peasycap is NULL\n"); ··· 3702 3769 SAM("MISTAKE: audio_isoc_buffer_size is unset\n"); 3703 3770 return -EFAULT; 3704 3771 } 3705 - /*---------------------------------------------------------------------------*/ 3706 - /* 3707 - * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST. 3708 - */ 3709 - /*---------------------------------------------------------------------------*/ 3772 + 3773 + /* 3774 + * Allocate memory for audio buffers. 3775 + * Lists must be initialized first. 3776 + */ 3710 3777 INIT_LIST_HEAD(&(peasycap->urb_audio_head)); 3711 3778 peasycap->purb_audio_head = &(peasycap->urb_audio_head); 3712 3779 3713 - /*---------------------------------------------------------------------------*/ 3714 3780 JOM(4, "allocating %i isoc audio buffers of size %i\n", 3715 3781 AUDIO_ISOC_BUFFER_MANY, 3716 3782 peasycap->audio_isoc_buffer_size); ··· 3732 3800 peasycap->audio_isoc_buffer[k].kount = k; 3733 3801 } 3734 3802 JOM(4, "allocation of isoc audio buffers done.\n"); 3735 - /*---------------------------------------------------------------------------*/ 3736 - /* 3737 - * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... 3738 - */ 3739 - /*---------------------------------------------------------------------------*/ 3803 + 3804 + /* Allocate and initialize urbs */ 3740 3805 JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); 3741 3806 JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", 3742 3807 peasycap->audio_isoc_framesperdesc); ··· 3751 3822 return -ENOMEM; 3752 3823 } 3753 3824 peasycap->allocation_audio_urb += 1 ; 3754 - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 3755 3825 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); 3756 3826 if (!pdata_urb) { 3757 3827 usb_free_urb(purb); ··· 3765 3837 pdata_urb->length = 0; 3766 3838 list_add_tail(&(pdata_urb->list_head), 3767 3839 peasycap->purb_audio_head); 3768 - /*---------------------------------------------------------------------------*/ 3769 - /* 3770 - * ... AND INITIALIZE THEM 3771 - */ 3772 - /*---------------------------------------------------------------------------*/ 3840 + 3773 3841 if (!k) { 3774 3842 JOM(4, "initializing audio urbs thus:\n"); 3775 3843 JOM(4, " purb->interval = 1;\n"); ··· 3813 3889 } 3814 3890 } 3815 3891 JOM(4, "allocation of %i struct urb done.\n", k); 3816 - /*---------------------------------------------------------------------------*/ 3817 - /* 3818 - * SAVE POINTER peasycap IN THIS INTERFACE. 3819 - */ 3820 - /*---------------------------------------------------------------------------*/ 3892 + 3893 + /* Save pointer peasycap in this interface */ 3821 3894 usb_set_intfdata(intf, peasycap); 3822 - /*---------------------------------------------------------------------------*/ 3823 - /* 3824 - * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. 3825 - */ 3826 - /*---------------------------------------------------------------------------*/ 3895 + 3896 + /* The audio device can now be registered */ 3827 3897 JOM(4, "initializing ALSA card\n"); 3828 3898 3829 3899 rc = easycap_alsa_probe(peasycap); ··· 3833 3915 peasycap->registered_audio++; 3834 3916 break; 3835 3917 } 3836 - /*---------------------------------------------------------------------------*/ 3837 - /* 3838 - * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED 3839 - */ 3840 - /*---------------------------------------------------------------------------*/ 3918 + /* Interfaces other than 0,1,2 are unexpected */ 3841 3919 default: 3842 3920 JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); 3843 3921 return -EINVAL;
+4 -4
drivers/staging/media/go7007/go7007-v4l2.c
··· 1050 1050 return 0; 1051 1051 } 1052 1052 1053 - /* VIDIOC_ENUMSTD on go7007 were used for enumberating the supported fps and 1053 + /* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and 1054 1054 its resolution, when the device is not connected to TV. 1055 - This were an API abuse, probably used by the lack of specific IOCTL's to 1056 - enumberate it, by the time the driver were written. 1055 + This is were an API abuse, probably used by the lack of specific IOCTL's to 1056 + enumerate it, by the time the driver was written. 1057 1057 1058 1058 However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS 1059 1059 and VIDIOC_ENUM_FRAMESIZES) were added for this purpose. 1060 1060 1061 - The two functions bellow implements the newer ioctls 1061 + The two functions below implement the newer ioctls 1062 1062 */ 1063 1063 static int vidioc_enum_framesizes(struct file *filp, void *priv, 1064 1064 struct v4l2_frmsizeenum *fsize)
+11 -7
drivers/staging/media/go7007/s2250-board.c
··· 192 192 { 193 193 struct go7007 *go = i2c_get_adapdata(client->adapter); 194 194 struct go7007_usb *usb; 195 + int rc; 195 196 u8 *buf; 196 197 struct s2250 *dec = i2c_get_clientdata(client); 197 198 ··· 217 216 kfree(buf); 218 217 return -EINTR; 219 218 } 220 - if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) { 219 + rc = go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1); 220 + mutex_unlock(&usb->i2c_lock); 221 + if (rc < 0) { 221 222 kfree(buf); 222 - return -EFAULT; 223 + return rc; 223 224 } 224 225 225 - mutex_unlock(&usb->i2c_lock); 226 226 if (buf[0] == 0) { 227 227 unsigned int subaddr, val_read; 228 228 ··· 256 254 { 257 255 struct go7007 *go = i2c_get_adapdata(client->adapter); 258 256 struct go7007_usb *usb; 257 + int rc; 259 258 u8 *buf; 260 259 261 260 if (go == NULL) ··· 279 276 kfree(buf); 280 277 return -EINTR; 281 278 } 282 - if (go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1) < 0) { 283 - kfree(buf); 284 - return -EFAULT; 285 - } 279 + rc = go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1); 286 280 mutex_unlock(&usb->i2c_lock); 281 + if (rc < 0) { 282 + kfree(buf); 283 + return rc; 284 + } 287 285 288 286 *val = (buf[0] << 8) | buf[1]; 289 287 kfree(buf);
+1 -1
drivers/staging/media/lirc/lirc_serial.c
··· 1282 1282 /* 1283 1283 * some architectures (e.g. intel xscale) align the 8bit serial registers 1284 1284 * on 32bit word boundaries. 1285 - * See linux-kernel/serial/8250.c serial_in()/out() 1285 + * See linux-kernel/drivers/tty/serial/8250/8250.c serial_in()/out() 1286 1286 */ 1287 1287 module_param(ioshift, int, S_IRUGO); 1288 1288 MODULE_PARM_DESC(ioshift, "shift I/O register offset (0 = no shift)");
+1 -1
drivers/staging/media/solo6x10/Kconfig
··· 5 5 select SND_PCM 6 6 ---help--- 7 7 This driver supports the Softlogic based MPEG-4 and h.264 codec 8 - codec cards. 8 + cards.
+14 -14
drivers/staging/media/solo6x10/core.c
··· 195 195 SOLO6010_SYS_CFG_OUTDIV(3); 196 196 solo_reg_write(solo_dev, SOLO_SYS_CFG, reg); 197 197 198 - if (solo_dev->flags & FLAGS_6110) { 199 - u32 sys_clock_MHz = SOLO_CLOCK_MHZ; 200 - u32 pll_DIVQ; 201 - u32 pll_DIVF; 198 + if (solo_dev->flags & FLAGS_6110) { 199 + u32 sys_clock_MHz = SOLO_CLOCK_MHZ; 200 + u32 pll_DIVQ; 201 + u32 pll_DIVF; 202 202 203 - if (sys_clock_MHz < 125) { 204 - pll_DIVQ = 3; 205 - pll_DIVF = (sys_clock_MHz * 4) / 3; 206 - } else { 207 - pll_DIVQ = 2; 208 - pll_DIVF = (sys_clock_MHz * 2) / 3; 209 - } 203 + if (sys_clock_MHz < 125) { 204 + pll_DIVQ = 3; 205 + pll_DIVF = (sys_clock_MHz * 4) / 3; 206 + } else { 207 + pll_DIVQ = 2; 208 + pll_DIVF = (sys_clock_MHz * 2) / 3; 209 + } 210 210 211 - solo_reg_write(solo_dev, SOLO6110_PLL_CONFIG, 211 + solo_reg_write(solo_dev, SOLO6110_PLL_CONFIG, 212 212 SOLO6110_PLL_RANGE_5_10MHZ | 213 213 SOLO6110_PLL_DIVR(9) | 214 214 SOLO6110_PLL_DIVQ_EXP(pll_DIVQ) | 215 215 SOLO6110_PLL_DIVF(pll_DIVF) | SOLO6110_PLL_FSEN); 216 - mdelay(1); // PLL Locking time (1ms) 216 + mdelay(1); /* PLL Locking time (1ms) */ 217 217 218 218 solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 3 << 8); /* ? */ 219 - } else 219 + } else 220 220 solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 1 << 8); /* ? */ 221 221 222 222 solo_reg_write(solo_dev, SOLO_TIMER_CLOCK_NUM, SOLO_CLOCK_MHZ - 1);
+5 -1
include/linux/ivtv.h
··· 58 58 __u32 src_height; 59 59 }; 60 60 61 - #define IVTV_IOC_DMA_FRAME _IOW ('V', BASE_VIDIOC_PRIVATE+0, struct ivtv_dma_frame) 61 + #define IVTV_IOC_DMA_FRAME _IOW ('V', BASE_VIDIOC_PRIVATE+0, struct ivtv_dma_frame) 62 + 63 + /* Select the passthrough mode (if the argument is non-zero). In the passthrough 64 + mode the output of the encoder is passed immediately into the decoder. */ 65 + #define IVTV_IOC_PASSTHROUGH_MODE _IOW ('V', BASE_VIDIOC_PRIVATE+1, int) 62 66 63 67 /* Deprecated defines: applications should use the defines from videodev2.h */ 64 68 #define IVTV_SLICED_TYPE_TELETEXT_B V4L2_MPEG_VBI_IVTV_TELETEXT_B
+125 -24
include/linux/videodev2.h
··· 235 235 __u32 denominator; 236 236 }; 237 237 238 - /* 239 - * D R I V E R C A P A B I L I T I E S 240 - */ 238 + /** 239 + * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP 240 + * 241 + * @driver: name of the driver module (e.g. "bttv") 242 + * @card: name of the card (e.g. "Hauppauge WinTV") 243 + * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) ) 244 + * @version: KERNEL_VERSION 245 + * @capabilities: capabilities of the physical device as a whole 246 + * @device_caps: capabilities accessed via this particular device (node) 247 + * @reserved: reserved fields for future extensions 248 + */ 241 249 struct v4l2_capability { 242 - __u8 driver[16]; /* i.e. "bttv" */ 243 - __u8 card[32]; /* i.e. "Hauppauge WinTV" */ 244 - __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ 245 - __u32 version; /* should use KERNEL_VERSION() */ 246 - __u32 capabilities; /* Device capabilities */ 247 - __u32 reserved[4]; 250 + __u8 driver[16]; 251 + __u8 card[32]; 252 + __u8 bus_info[32]; 253 + __u32 version; 254 + __u32 capabilities; 255 + __u32 device_caps; 256 + __u32 reserved[3]; 248 257 }; 249 258 250 259 /* Values for 'capabilities' field */ ··· 282 273 #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ 283 274 #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ 284 275 #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ 276 + 277 + #define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ 285 278 286 279 /* 287 280 * V I D E O I M A G E F O R M A T ··· 762 751 763 752 /* Selection targets */ 764 753 765 - /* current cropping area */ 766 - #define V4L2_SEL_TGT_CROP_ACTIVE 0 767 - /* default cropping area */ 768 - #define V4L2_SEL_TGT_CROP_DEFAULT 1 769 - /* cropping bounds */ 770 - #define V4L2_SEL_TGT_CROP_BOUNDS 2 771 - /* current composing area */ 772 - #define V4L2_SEL_TGT_COMPOSE_ACTIVE 256 773 - /* default composing area */ 774 - #define V4L2_SEL_TGT_COMPOSE_DEFAULT 257 775 - /* composing bounds */ 776 - #define V4L2_SEL_TGT_COMPOSE_BOUNDS 258 777 - /* current composing area plus all padding pixels */ 778 - #define V4L2_SEL_TGT_COMPOSE_PADDED 259 754 + /* Current cropping area */ 755 + #define V4L2_SEL_TGT_CROP_ACTIVE 0x0000 756 + /* Default cropping area */ 757 + #define V4L2_SEL_TGT_CROP_DEFAULT 0x0001 758 + /* Cropping bounds */ 759 + #define V4L2_SEL_TGT_CROP_BOUNDS 0x0002 760 + /* Current composing area */ 761 + #define V4L2_SEL_TGT_COMPOSE_ACTIVE 0x0100 762 + /* Default composing area */ 763 + #define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101 764 + /* Composing bounds */ 765 + #define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102 766 + /* Current composing area plus all padding pixels */ 767 + #define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103 779 768 780 769 /** 781 770 * struct v4l2_selection - selection info ··· 785 774 * @r: coordinates of selection window 786 775 * @reserved: for future use, rounds structure size to 64 bytes, set to zero 787 776 * 788 - * Hardware may use multiple helper window to process a video stream. 777 + * Hardware may use multiple helper windows to process a video stream. 789 778 * The structure is used to exchange this selection areas between 790 779 * an application and a driver. 791 780 */ ··· 1136 1125 #define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ 1137 1126 #define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */ 1138 1127 #define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */ 1128 + #define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */ 1139 1129 1140 1130 #define V4L2_CTRL_ID_MASK (0x0fffffff) 1141 1131 #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) ··· 1408 1396 V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, 1409 1397 V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, 1410 1398 }; 1399 + #define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE+112) 1400 + enum v4l2_mpeg_audio_dec_playback { 1401 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0, 1402 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1, 1403 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2, 1404 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3, 1405 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4, 1406 + V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5, 1407 + }; 1408 + #define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113) 1411 1409 1412 1410 /* MPEG video controls specific to multiplexed streams */ 1413 1411 #define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) ··· 1468 1446 V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2, 1469 1447 }; 1470 1448 #define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222) 1449 + #define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223) 1450 + #define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224) 1451 + 1471 1452 #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) 1472 1453 #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) 1473 1454 #define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) ··· 1759 1734 #define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) 1760 1735 #define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) 1761 1736 1737 + /* JPEG-class control IDs defined by V4L2 */ 1738 + #define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900) 1739 + #define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1) 1740 + 1741 + #define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1) 1742 + enum v4l2_jpeg_chroma_subsampling { 1743 + V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0, 1744 + V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1, 1745 + V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2, 1746 + V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3, 1747 + V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4, 1748 + V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5, 1749 + }; 1750 + #define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2) 1751 + #define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3) 1752 + 1753 + #define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4) 1754 + #define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0) 1755 + #define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1) 1756 + #define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16) 1757 + #define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17) 1758 + #define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18) 1759 + 1762 1760 /* 1763 1761 * T U N I N G 1764 1762 */ ··· 1945 1897 }; 1946 1898 }; 1947 1899 1900 + /* Decoder commands */ 1901 + #define V4L2_DEC_CMD_START (0) 1902 + #define V4L2_DEC_CMD_STOP (1) 1903 + #define V4L2_DEC_CMD_PAUSE (2) 1904 + #define V4L2_DEC_CMD_RESUME (3) 1905 + 1906 + /* Flags for V4L2_DEC_CMD_START */ 1907 + #define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0) 1908 + 1909 + /* Flags for V4L2_DEC_CMD_PAUSE */ 1910 + #define V4L2_DEC_CMD_PAUSE_TO_BLACK (1 << 0) 1911 + 1912 + /* Flags for V4L2_DEC_CMD_STOP */ 1913 + #define V4L2_DEC_CMD_STOP_TO_BLACK (1 << 0) 1914 + #define V4L2_DEC_CMD_STOP_IMMEDIATELY (1 << 1) 1915 + 1916 + /* Play format requirements (returned by the driver): */ 1917 + 1918 + /* The decoder has no special format requirements */ 1919 + #define V4L2_DEC_START_FMT_NONE (0) 1920 + /* The decoder requires full GOPs */ 1921 + #define V4L2_DEC_START_FMT_GOP (1) 1922 + 1923 + /* The structure must be zeroed before use by the application 1924 + This ensures it can be extended safely in the future. */ 1925 + struct v4l2_decoder_cmd { 1926 + __u32 cmd; 1927 + __u32 flags; 1928 + union { 1929 + struct { 1930 + __u64 pts; 1931 + } stop; 1932 + 1933 + struct { 1934 + /* 0 or 1000 specifies normal speed, 1935 + 1 specifies forward single stepping, 1936 + -1 specifies backward single stepping, 1937 + >1: playback at speed/1000 of the normal speed, 1938 + <-1: reverse playback at (-speed/1000) of the normal speed. */ 1939 + __s32 speed; 1940 + __u32 format; 1941 + } start; 1942 + 1943 + struct { 1944 + __u32 data[16]; 1945 + } raw; 1946 + }; 1947 + }; 1948 1948 #endif 1949 1949 1950 1950 ··· 2402 2306 /* Experimental selection API */ 2403 2307 #define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection) 2404 2308 #define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection) 2309 + 2310 + /* Experimental, these two ioctls may change over the next couple of kernel 2311 + versions. */ 2312 + #define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd) 2313 + #define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd) 2405 2314 2406 2315 /* Reminder: when adding new ioctls please add support for them to 2407 2316 drivers/media/video/v4l2-compat-ioctl32.c as well! */
+47
include/media/adv7183.h
··· 1 + /* 2 + * adv7183.h - definition for adv7183 inputs and outputs 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 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 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #ifndef _ADV7183_H_ 21 + #define _ADV7183_H_ 22 + 23 + /* ADV7183 HW inputs */ 24 + #define ADV7183_COMPOSITE0 0 /* CVBS in on AIN1 */ 25 + #define ADV7183_COMPOSITE1 1 /* CVBS in on AIN2 */ 26 + #define ADV7183_COMPOSITE2 2 /* CVBS in on AIN3 */ 27 + #define ADV7183_COMPOSITE3 3 /* CVBS in on AIN4 */ 28 + #define ADV7183_COMPOSITE4 4 /* CVBS in on AIN5 */ 29 + #define ADV7183_COMPOSITE5 5 /* CVBS in on AIN6 */ 30 + #define ADV7183_COMPOSITE6 6 /* CVBS in on AIN7 */ 31 + #define ADV7183_COMPOSITE7 7 /* CVBS in on AIN8 */ 32 + #define ADV7183_COMPOSITE8 8 /* CVBS in on AIN9 */ 33 + #define ADV7183_COMPOSITE9 9 /* CVBS in on AIN10 */ 34 + #define ADV7183_COMPOSITE10 10 /* CVBS in on AIN11 */ 35 + 36 + #define ADV7183_SVIDEO0 11 /* Y on AIN1, C on AIN4 */ 37 + #define ADV7183_SVIDEO1 12 /* Y on AIN2, C on AIN5 */ 38 + #define ADV7183_SVIDEO2 13 /* Y on AIN3, C on AIN6 */ 39 + 40 + #define ADV7183_COMPONENT0 14 /* Y on AIN1, Pr on AIN4, Pb on AIN5 */ 41 + #define ADV7183_COMPONENT1 15 /* Y on AIN2, Pr on AIN3, Pb on AIN6 */ 42 + 43 + /* ADV7183 HW outputs */ 44 + #define ADV7183_8BIT_OUT 0 45 + #define ADV7183_16BIT_OUT 1 46 + 47 + #endif
+37
include/media/blackfin/bfin_capture.h
··· 1 + #ifndef _BFIN_CAPTURE_H_ 2 + #define _BFIN_CAPTURE_H_ 3 + 4 + #include <linux/i2c.h> 5 + 6 + struct v4l2_input; 7 + struct ppi_info; 8 + 9 + struct bcap_route { 10 + u32 input; 11 + u32 output; 12 + }; 13 + 14 + struct bfin_capture_config { 15 + /* card name */ 16 + char *card_name; 17 + /* inputs available at the sub device */ 18 + struct v4l2_input *inputs; 19 + /* number of inputs supported */ 20 + int num_inputs; 21 + /* routing information for each input */ 22 + struct bcap_route *routes; 23 + /* i2c bus adapter no */ 24 + int i2c_adapter_id; 25 + /* i2c subdevice board info */ 26 + struct i2c_board_info board_info; 27 + /* ppi board info */ 28 + const struct ppi_info *ppi_info; 29 + /* ppi control */ 30 + unsigned long ppi_control; 31 + /* ppi interrupt mask */ 32 + u32 int_mask; 33 + /* horizontal blanking clocks */ 34 + int blank_clocks; 35 + }; 36 + 37 + #endif
+74
include/media/blackfin/ppi.h
··· 1 + /* 2 + * Analog Devices PPI header file 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 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 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 + */ 19 + 20 + #ifndef _PPI_H_ 21 + #define _PPI_H_ 22 + 23 + #include <linux/interrupt.h> 24 + 25 + #ifdef EPPI_EN 26 + #define PORT_EN EPPI_EN 27 + #define DMA32 0 28 + #define PACK_EN PACKEN 29 + #endif 30 + 31 + struct ppi_if; 32 + 33 + struct ppi_params { 34 + int width; 35 + int height; 36 + int bpp; 37 + unsigned long ppi_control; 38 + u32 int_mask; 39 + int blank_clocks; 40 + }; 41 + 42 + struct ppi_ops { 43 + int (*attach_irq)(struct ppi_if *ppi, irq_handler_t handler); 44 + void (*detach_irq)(struct ppi_if *ppi); 45 + int (*start)(struct ppi_if *ppi); 46 + int (*stop)(struct ppi_if *ppi); 47 + int (*set_params)(struct ppi_if *ppi, struct ppi_params *params); 48 + void (*update_addr)(struct ppi_if *ppi, unsigned long addr); 49 + }; 50 + 51 + enum ppi_type { 52 + PPI_TYPE_PPI, 53 + PPI_TYPE_EPPI, 54 + }; 55 + 56 + struct ppi_info { 57 + enum ppi_type type; 58 + int dma_ch; 59 + int irq_err; 60 + void __iomem *base; 61 + const unsigned short *pin_req; 62 + }; 63 + 64 + struct ppi_if { 65 + unsigned long ppi_control; 66 + const struct ppi_ops *ops; 67 + const struct ppi_info *info; 68 + bool err_int; 69 + void *priv; 70 + }; 71 + 72 + struct ppi_if *ppi_create_instance(const struct ppi_info *info); 73 + void ppi_delete_instance(struct ppi_if *ppi); 74 + #endif
+2
include/media/davinci/vpif_types.h
··· 17 17 #ifndef _VPIF_TYPES_H 18 18 #define _VPIF_TYPES_H 19 19 20 + #include <linux/i2c.h> 21 + 20 22 #define VPIF_CAPTURE_MAX_CHANNELS 2 21 23 22 24 enum vpif_if_type {
+22
include/media/gpio-ir-recv.h
··· 1 + /* Copyright (c) 2012, Code Aurora Forum. All rights reserved. 2 + * 3 + * This program is free software; you can redistribute it and/or modify 4 + * it under the terms of the GNU General Public License version 2 and 5 + * only version 2 as published by the Free Software Foundation. 6 + * 7 + * This program is distributed in the hope that it will be useful, 8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 + * GNU General Public License for more details. 11 + */ 12 + 13 + #ifndef __GPIO_IR_RECV_H__ 14 + #define __GPIO_IR_RECV_H__ 15 + 16 + struct gpio_ir_recv_platform_data { 17 + int gpio_nr; 18 + bool active_low; 19 + }; 20 + 21 + #endif /* __GPIO_IR_RECV_H__ */ 22 +
+36
include/media/mt9m032.h
··· 1 + /* 2 + * Driver for MT9M032 CMOS Image Sensor from Micron 3 + * 4 + * Copyright (C) 2010-2011 Lund Engineering 5 + * Contact: Gil Lund <gwlund@lundeng.com> 6 + * Author: Martin Hostettler <martin@neutronstar.dyndns.org> 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * version 2 as published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, but 13 + * WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 + * 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., 51 Franklin St, Fifth Floor, Boston, MA 20 + * 02110-1301 USA 21 + * 22 + */ 23 + 24 + #ifndef MT9M032_H 25 + #define MT9M032_H 26 + 27 + #define MT9M032_NAME "mt9m032" 28 + #define MT9M032_I2C_ADDR (0xb8 >> 1) 29 + 30 + struct mt9m032_platform_data { 31 + u32 ext_clock; 32 + u32 pix_clock; 33 + bool invert_pixclock; 34 + 35 + }; 36 + #endif /* MT9M032_H */
+3
include/media/rc-map.h
··· 102 102 #define RC_MAP_IMON_MCE "rc-imon-mce" 103 103 #define RC_MAP_IMON_PAD "rc-imon-pad" 104 104 #define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e" 105 + #define RC_MAP_IT913X_V1 "rc-it913x-v1" 106 + #define RC_MAP_IT913X_V2 "rc-it913x-v2" 105 107 #define RC_MAP_KAIOMY "rc-kaiomy" 106 108 #define RC_MAP_KWORLD_315U "rc-kworld-315u" 109 + #define RC_MAP_KWORLD_PC150U "rc-kworld-pc150u" 107 110 #define RC_MAP_KWORLD_PLUS_TV_ANALOG "rc-kworld-plus-tv-analog" 108 111 #define RC_MAP_LEADTEK_Y04G0051 "rc-leadtek-y04g0051" 109 112 #define RC_MAP_LIRC "rc-lirc"
+35
include/media/s5p_hdmi.h
··· 1 + /* 2 + * Driver header for S5P HDMI chip. 3 + * 4 + * Copyright (c) 2011 Samsung Electronics, Co. Ltd 5 + * Contact: Tomasz Stanislawski <t.stanislaws@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + */ 12 + 13 + #ifndef S5P_HDMI_H 14 + #define S5P_HDMI_H 15 + 16 + struct i2c_board_info; 17 + 18 + /** 19 + * @hdmiphy_bus: controller id for HDMIPHY bus 20 + * @hdmiphy_info: template for HDMIPHY I2C device 21 + * @mhl_bus: controller id for MHL control bus 22 + * @mhl_info: template for MHL I2C device 23 + * 24 + * NULL pointer for *_info fields indicates that 25 + * the corresponding chip is not present 26 + */ 27 + struct s5p_hdmi_platform_data { 28 + int hdmiphy_bus; 29 + struct i2c_board_info *hdmiphy_info; 30 + int mhl_bus; 31 + struct i2c_board_info *mhl_info; 32 + }; 33 + 34 + #endif /* S5P_HDMI_H */ 35 +
+2
include/media/sh_mobile_ceu.h
··· 18 18 19 19 struct sh_mobile_ceu_info { 20 20 unsigned long flags; 21 + int max_width; 22 + int max_height; 21 23 struct sh_mobile_ceu_companion *csi2; 22 24 }; 23 25
+24
include/media/sii9234.h
··· 1 + /* 2 + * Driver header for SII9234 MHL converter chip. 3 + * 4 + * Copyright (c) 2011 Samsung Electronics, Co. Ltd 5 + * Contact: Tomasz Stanislawski <t.stanislaws@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + */ 12 + 13 + #ifndef SII9234_H 14 + #define SII9234_H 15 + 16 + /** 17 + * @gpio_n_reset: GPIO driving nRESET pin 18 + */ 19 + 20 + struct sii9234_platform_data { 21 + int gpio_n_reset; 22 + }; 23 + 24 + #endif /* SII9234_H */
+1
include/media/tuner.h
··· 136 136 #define TUNER_TENA_TNF_5337 86 137 137 138 138 #define TUNER_XC4000 87 /* Xceive Silicon Tuner */ 139 + #define TUNER_XC5000C 88 /* Xceive Silicon Tuner */ 139 140 140 141 /* tv card specific */ 141 142 #define TDA9887_PRESENT (1<<0)
+6
include/media/v4l2-chip-ident.h
··· 143 143 /* module saa6588: just ident 6588 */ 144 144 V4L2_IDENT_SAA6588 = 6588, 145 145 146 + /* module vs6624: just ident 6624 */ 147 + V4L2_IDENT_VS6624 = 6624, 148 + 146 149 /* module saa6752hs: reserved range 6750-6759 */ 147 150 V4L2_IDENT_SAA6752HS = 6752, 148 151 V4L2_IDENT_SAA6752HS_AC3 = 6753, ··· 164 161 165 162 /* module adv7180: just ident 7180 */ 166 163 V4L2_IDENT_ADV7180 = 7180, 164 + 165 + /* module adv7183: just ident 7183 */ 166 + V4L2_IDENT_ADV7183 = 7183, 167 167 168 168 /* module saa7185: just ident 7185 */ 169 169 V4L2_IDENT_SAA7185 = 7185,
+13
include/media/v4l2-ctrls.h
··· 33 33 struct v4l2_subdev; 34 34 struct v4l2_subscribed_event; 35 35 struct v4l2_fh; 36 + struct poll_table_struct; 36 37 37 38 /** struct v4l2_ctrl_ops - The control operations that the driver has to provide. 38 39 * @g_volatile_ctrl: Get a new value for this control. Generally only relevant ··· 492 491 struct v4l2_subscribed_event *sev); 493 492 void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl, 494 493 struct v4l2_subscribed_event *sev); 494 + 495 + /* Can be used as a vidioc_log_status function that just dumps all controls 496 + associated with the filehandle. */ 497 + int v4l2_ctrl_log_status(struct file *file, void *fh); 498 + 499 + /* Can be used as a vidioc_subscribe_event function that just subscribes 500 + control events. */ 501 + int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh, 502 + struct v4l2_event_subscription *sub); 503 + 504 + /* Can be used as a poll function that just polls for control events. */ 505 + unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait); 495 506 496 507 /* Helpers for ioctl_ops. If hdl == NULL then they will all return -EINVAL. */ 497 508 int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc);
+3
include/media/v4l2-dev.h
··· 62 62 unsigned int (*poll) (struct file *, struct poll_table_struct *); 63 63 long (*ioctl) (struct file *, unsigned int, unsigned long); 64 64 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); 65 + #ifdef CONFIG_COMPAT 66 + long (*compat_ioctl32) (struct file *, unsigned int, unsigned long); 67 + #endif 65 68 unsigned long (*get_unmapped_area) (struct file *, unsigned long, 66 69 unsigned long, unsigned long, unsigned long); 67 70 int (*mmap) (struct file *, struct vm_area_struct *);
+4
include/media/v4l2-ioctl.h
··· 211 211 struct v4l2_encoder_cmd *a); 212 212 int (*vidioc_try_encoder_cmd) (struct file *file, void *fh, 213 213 struct v4l2_encoder_cmd *a); 214 + int (*vidioc_decoder_cmd) (struct file *file, void *fh, 215 + struct v4l2_decoder_cmd *a); 216 + int (*vidioc_try_decoder_cmd) (struct file *file, void *fh, 217 + struct v4l2_decoder_cmd *a); 214 218 215 219 /* Stream type-dependent parameter ioctls */ 216 220 int (*vidioc_g_parm) (struct file *file, void *fh,
+5 -1
include/sound/tea575x-tuner.h
··· 25 25 #include <linux/videodev2.h> 26 26 #include <media/v4l2-ctrls.h> 27 27 #include <media/v4l2-dev.h> 28 + #include <media/v4l2-device.h> 28 29 29 30 #define TEA575X_FMIF 10700 30 31 ··· 43 42 }; 44 43 45 44 struct snd_tea575x { 45 + struct v4l2_device *v4l2_dev; 46 46 struct video_device vd; /* video device */ 47 + int radio_nr; /* radio_nr */ 47 48 bool tea5759; /* 5759 chip is present */ 49 + bool cannot_read_data; /* Device cannot read the data pin */ 48 50 bool mute; /* Device is muted? */ 49 51 bool stereo; /* receiving stereo */ 50 52 bool tuned; /* tuned to a station */ 51 53 unsigned int val; /* hw value */ 52 - unsigned long freq; /* frequency */ 54 + u32 freq; /* frequency */ 53 55 struct mutex mutex; 54 56 struct snd_tea575x_ops *ops; 55 57 void *private_data;
+112 -55
sound/i2c/other/tea575x-tuner.c
··· 25 25 #include <linux/module.h> 26 26 #include <linux/init.h> 27 27 #include <linux/slab.h> 28 - #include <linux/version.h> 28 + #include <linux/sched.h> 29 + #include <media/v4l2-device.h> 29 30 #include <media/v4l2-dev.h> 31 + #include <media/v4l2-fh.h> 30 32 #include <media/v4l2-ioctl.h> 33 + #include <media/v4l2-event.h> 31 34 #include <sound/tea575x-tuner.h> 32 35 33 36 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 34 37 MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"); 35 38 MODULE_LICENSE("GPL"); 36 39 37 - static int radio_nr = -1; 38 - module_param(radio_nr, int, 0); 39 - 40 - #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) 41 - #define FREQ_LO (50UL * 16000) 42 - #define FREQ_HI (150UL * 16000) 40 + #define FREQ_LO (76U * 16000) 41 + #define FREQ_HI (108U * 16000) 43 42 44 43 /* 45 44 * definitions ··· 89 90 tea->ops->set_pins(tea, 0); 90 91 } 91 92 92 - static unsigned int snd_tea575x_read(struct snd_tea575x *tea) 93 + static u32 snd_tea575x_read(struct snd_tea575x *tea) 93 94 { 94 95 u16 l, rdata; 95 96 u32 data = 0; ··· 120 121 return data; 121 122 } 122 123 123 - static void snd_tea575x_get_freq(struct snd_tea575x *tea) 124 + static u32 snd_tea575x_get_freq(struct snd_tea575x *tea) 124 125 { 125 - unsigned long freq; 126 + u32 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK; 126 127 127 - freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK; 128 + if (freq == 0) 129 + return freq; 130 + 128 131 /* freq *= 12.5 */ 129 132 freq *= 125; 130 133 freq /= 10; ··· 136 135 else 137 136 freq -= TEA575X_FMIF; 138 137 139 - tea->freq = freq * 16; /* from kHz */ 138 + return clamp(freq * 16, FREQ_LO, FREQ_HI); /* from kHz */ 140 139 } 141 140 142 141 static void snd_tea575x_set_freq(struct snd_tea575x *tea) 143 142 { 144 - unsigned long freq; 143 + u32 freq = tea->freq; 145 144 146 - freq = clamp(tea->freq, FREQ_LO, FREQ_HI); 147 145 freq /= 16; /* to kHz */ 148 146 /* crystal fixup */ 149 147 if (tea->tea5759) ··· 167 167 { 168 168 struct snd_tea575x *tea = video_drvdata(file); 169 169 170 - strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); 170 + strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver)); 171 171 strlcpy(v->card, tea->card, sizeof(v->card)); 172 172 strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card)); 173 173 strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info)); 174 - v->version = RADIO_VERSION; 175 - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 174 + v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 175 + if (!tea->cannot_read_data) 176 + v->device_caps |= V4L2_CAP_HW_FREQ_SEEK; 177 + v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS; 176 178 return 0; 177 179 } 178 180 ··· 193 191 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 194 192 v->rangelow = FREQ_LO; 195 193 v->rangehigh = FREQ_HI; 196 - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 197 - v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; 194 + v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; 195 + v->audmode = (tea->val & TEA575X_BIT_MONO) ? 196 + V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO; 198 197 v->signal = tea->tuned ? 0xffff : 0; 199 - 200 198 return 0; 201 199 } 202 200 203 201 static int vidioc_s_tuner(struct file *file, void *priv, 204 202 struct v4l2_tuner *v) 205 203 { 206 - if (v->index > 0) 204 + struct snd_tea575x *tea = video_drvdata(file); 205 + 206 + if (v->index) 207 207 return -EINVAL; 208 + tea->val &= ~TEA575X_BIT_MONO; 209 + if (v->audmode == V4L2_TUNER_MODE_MONO) 210 + tea->val |= TEA575X_BIT_MONO; 211 + snd_tea575x_write(tea, tea->val); 208 212 return 0; 209 213 } 210 214 ··· 222 214 if (f->tuner != 0) 223 215 return -EINVAL; 224 216 f->type = V4L2_TUNER_RADIO; 225 - snd_tea575x_get_freq(tea); 226 217 f->frequency = tea->freq; 227 218 return 0; 228 219 } ··· 234 227 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 235 228 return -EINVAL; 236 229 237 - if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) 238 - return -EINVAL; 239 - 240 - tea->freq = f->frequency; 241 - 230 + tea->val &= ~TEA575X_BIT_SEARCH; 231 + tea->freq = clamp(f->frequency, FREQ_LO, FREQ_HI); 242 232 snd_tea575x_set_freq(tea); 243 - 244 233 return 0; 245 234 } 246 235 247 - static int vidioc_g_audio(struct file *file, void *priv, 248 - struct v4l2_audio *a) 236 + static int vidioc_s_hw_freq_seek(struct file *file, void *fh, 237 + struct v4l2_hw_freq_seek *a) 249 238 { 250 - if (a->index > 1) 239 + struct snd_tea575x *tea = video_drvdata(file); 240 + unsigned long timeout; 241 + int i; 242 + 243 + if (tea->cannot_read_data) 244 + return -ENOTTY; 245 + if (a->tuner || a->wrap_around) 251 246 return -EINVAL; 252 247 253 - strcpy(a->name, "Radio"); 254 - a->capability = V4L2_AUDCAP_STEREO; 255 - return 0; 256 - } 248 + /* clear the frequency, HW will fill it in */ 249 + tea->val &= ~TEA575X_BIT_FREQ_MASK; 250 + tea->val |= TEA575X_BIT_SEARCH; 251 + if (a->seek_upward) 252 + tea->val |= TEA575X_BIT_UPDOWN; 253 + else 254 + tea->val &= ~TEA575X_BIT_UPDOWN; 255 + snd_tea575x_write(tea, tea->val); 256 + timeout = jiffies + msecs_to_jiffies(10000); 257 + for (;;) { 258 + if (time_after(jiffies, timeout)) 259 + break; 260 + if (schedule_timeout_interruptible(msecs_to_jiffies(10))) { 261 + /* some signal arrived, stop search */ 262 + tea->val &= ~TEA575X_BIT_SEARCH; 263 + snd_tea575x_set_freq(tea); 264 + return -ERESTARTSYS; 265 + } 266 + if (!(snd_tea575x_read(tea) & TEA575X_BIT_SEARCH)) { 267 + u32 freq; 257 268 258 - static int vidioc_s_audio(struct file *file, void *priv, 259 - struct v4l2_audio *a) 260 - { 261 - if (a->index != 0) 262 - return -EINVAL; 263 - return 0; 269 + /* Found a frequency, wait until it can be read */ 270 + for (i = 0; i < 100; i++) { 271 + msleep(10); 272 + freq = snd_tea575x_get_freq(tea); 273 + if (freq) /* available */ 274 + break; 275 + } 276 + if (freq == 0) /* shouldn't happen */ 277 + break; 278 + /* 279 + * if we moved by less than 50 kHz, or in the wrong 280 + * direction, continue seeking 281 + */ 282 + if (abs(tea->freq - freq) < 16 * 50 || 283 + (a->seek_upward && freq < tea->freq) || 284 + (!a->seek_upward && freq > tea->freq)) { 285 + snd_tea575x_write(tea, tea->val); 286 + continue; 287 + } 288 + tea->freq = freq; 289 + tea->val &= ~TEA575X_BIT_SEARCH; 290 + return 0; 291 + } 292 + } 293 + tea->val &= ~TEA575X_BIT_SEARCH; 294 + snd_tea575x_set_freq(tea); 295 + return -EAGAIN; 264 296 } 265 297 266 298 static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) ··· 319 273 static const struct v4l2_file_operations tea575x_fops = { 320 274 .owner = THIS_MODULE, 321 275 .unlocked_ioctl = video_ioctl2, 276 + .open = v4l2_fh_open, 277 + .release = v4l2_fh_release, 278 + .poll = v4l2_ctrl_poll, 322 279 }; 323 280 324 281 static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { 325 282 .vidioc_querycap = vidioc_querycap, 326 283 .vidioc_g_tuner = vidioc_g_tuner, 327 284 .vidioc_s_tuner = vidioc_s_tuner, 328 - .vidioc_g_audio = vidioc_g_audio, 329 - .vidioc_s_audio = vidioc_s_audio, 330 285 .vidioc_g_frequency = vidioc_g_frequency, 331 286 .vidioc_s_frequency = vidioc_s_frequency, 287 + .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek, 288 + .vidioc_log_status = v4l2_ctrl_log_status, 289 + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 290 + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 332 291 }; 333 292 334 - static struct video_device tea575x_radio = { 335 - .name = "tea575x-tuner", 293 + static const struct video_device tea575x_radio = { 336 294 .fops = &tea575x_fops, 337 295 .ioctl_ops = &tea575x_ioctl_ops, 338 - .release = video_device_release_empty, 296 + .release = video_device_release_empty, 339 297 }; 340 298 341 299 static const struct v4l2_ctrl_ops tea575x_ctrl_ops = { ··· 353 303 { 354 304 int retval; 355 305 356 - tea->mute = 1; 306 + tea->mute = true; 357 307 358 - snd_tea575x_write(tea, 0x55AA); 359 - if (snd_tea575x_read(tea) != 0x55AA) 360 - return -ENODEV; 308 + /* Not all devices can or know how to read the data back. 309 + Such devices can set cannot_read_data to true. */ 310 + if (!tea->cannot_read_data) { 311 + snd_tea575x_write(tea, 0x55AA); 312 + if (snd_tea575x_read(tea) != 0x55AA) 313 + return -ENODEV; 314 + } 361 315 362 - tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; 316 + tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28; 363 317 tea->freq = 90500 * 16; /* 90.5Mhz default */ 364 318 snd_tea575x_set_freq(tea); 365 319 366 320 tea->vd = tea575x_radio; 367 321 video_set_drvdata(&tea->vd, tea); 368 322 mutex_init(&tea->mutex); 323 + strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name)); 369 324 tea->vd.lock = &tea->mutex; 325 + tea->vd.v4l2_dev = tea->v4l2_dev; 326 + tea->vd.ctrl_handler = &tea->ctrl_handler; 327 + set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags); 370 328 371 329 v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); 372 - tea->vd.ctrl_handler = &tea->ctrl_handler; 373 330 v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); 374 331 retval = tea->ctrl_handler.error; 375 332 if (retval) { 376 - printk(KERN_ERR "tea575x-tuner: can't initialize controls\n"); 333 + v4l2_err(tea->v4l2_dev, "can't initialize controls\n"); 377 334 v4l2_ctrl_handler_free(&tea->ctrl_handler); 378 335 return retval; 379 336 } ··· 395 338 396 339 v4l2_ctrl_handler_setup(&tea->ctrl_handler); 397 340 398 - retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, radio_nr); 341 + retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr); 399 342 if (retval) { 400 - printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); 343 + v4l2_err(tea->v4l2_dev, "can't register video device!\n"); 401 344 v4l2_ctrl_handler_free(&tea->ctrl_handler); 402 345 return retval; 403 346 }
+15
sound/pci/es1968.c
··· 142 142 #ifdef SUPPORT_JOYSTICK 143 143 static bool joystick[SNDRV_CARDS]; 144 144 #endif 145 + static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; 145 146 146 147 module_param_array(index, int, NULL, 0444); 147 148 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); ··· 166 165 module_param_array(joystick, bool, NULL, 0444); 167 166 MODULE_PARM_DESC(joystick, "Enable joystick."); 168 167 #endif 168 + module_param_array(radio_nr, int, NULL, 0444); 169 + MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 170 + 169 171 170 172 171 173 #define NR_APUS 64 ··· 562 558 struct work_struct hwvol_work; 563 559 564 560 #ifdef CONFIG_SND_ES1968_RADIO 561 + struct v4l2_device v4l2_dev; 565 562 struct snd_tea575x tea; 566 563 #endif 567 564 }; ··· 2618 2613 2619 2614 #ifdef CONFIG_SND_ES1968_RADIO 2620 2615 snd_tea575x_exit(&chip->tea); 2616 + v4l2_device_unregister(&chip->v4l2_dev); 2621 2617 #endif 2622 2618 2623 2619 if (chip->irq >= 0) ··· 2661 2655 int capt_streams, 2662 2656 int chip_type, 2663 2657 int do_pm, 2658 + int radio_nr, 2664 2659 struct es1968 **chip_ret) 2665 2660 { 2666 2661 static struct snd_device_ops ops = { ··· 2758 2751 snd_card_set_dev(card, &pci->dev); 2759 2752 2760 2753 #ifdef CONFIG_SND_ES1968_RADIO 2754 + err = v4l2_device_register(&pci->dev, &chip->v4l2_dev); 2755 + if (err < 0) { 2756 + snd_es1968_free(chip); 2757 + return err; 2758 + } 2759 + chip->tea.v4l2_dev = &chip->v4l2_dev; 2761 2760 chip->tea.private_data = chip; 2761 + chip->tea.radio_nr = radio_nr; 2762 2762 chip->tea.ops = &snd_es1968_tea_ops; 2763 2763 strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); 2764 2764 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); ··· 2811 2797 pcm_substreams_c[dev], 2812 2798 pci_id->driver_data, 2813 2799 use_pm[dev], 2800 + radio_nr[dev], 2814 2801 &chip)) < 0) { 2815 2802 snd_card_free(card); 2816 2803 return err;
+18 -2
sound/pci/fm801.c
··· 58 58 * High 16-bits are video (radio) device number + 1 59 59 */ 60 60 static int tea575x_tuner[SNDRV_CARDS]; 61 + static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; 61 62 62 63 module_param_array(index, int, NULL, 0444); 63 64 MODULE_PARM_DESC(index, "Index value for the FM801 soundcard."); ··· 68 67 MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); 69 68 module_param_array(tea575x_tuner, int, NULL, 0444); 70 69 MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only)."); 70 + module_param_array(radio_nr, int, NULL, 0444); 71 + MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 72 + 71 73 72 74 #define TUNER_DISABLED (1<<3) 73 75 #define TUNER_ONLY (1<<4) ··· 201 197 struct snd_info_entry *proc_entry; 202 198 203 199 #ifdef CONFIG_SND_FM801_TEA575X_BOOL 200 + struct v4l2_device v4l2_dev; 204 201 struct snd_tea575x tea; 205 202 #endif 206 203 ··· 1159 1154 1160 1155 __end_hw: 1161 1156 #ifdef CONFIG_SND_FM801_TEA575X_BOOL 1162 - if (!(chip->tea575x_tuner & TUNER_DISABLED)) 1157 + if (!(chip->tea575x_tuner & TUNER_DISABLED)) { 1163 1158 snd_tea575x_exit(&chip->tea); 1159 + v4l2_device_unregister(&chip->v4l2_dev); 1160 + } 1164 1161 #endif 1165 1162 if (chip->irq >= 0) 1166 1163 free_irq(chip->irq, chip); ··· 1182 1175 static int __devinit snd_fm801_create(struct snd_card *card, 1183 1176 struct pci_dev * pci, 1184 1177 int tea575x_tuner, 1178 + int radio_nr, 1185 1179 struct fm801 ** rchip) 1186 1180 { 1187 1181 struct fm801 *chip; ··· 1242 1234 snd_card_set_dev(card, &pci->dev); 1243 1235 1244 1236 #ifdef CONFIG_SND_FM801_TEA575X_BOOL 1237 + err = v4l2_device_register(&pci->dev, &chip->v4l2_dev); 1238 + if (err < 0) { 1239 + snd_fm801_free(chip); 1240 + return err; 1241 + } 1242 + chip->tea.v4l2_dev = &chip->v4l2_dev; 1243 + chip->tea.radio_nr = radio_nr; 1245 1244 chip->tea.private_data = chip; 1246 1245 chip->tea.ops = &snd_fm801_tea_ops; 1247 1246 sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); ··· 1256 1241 (tea575x_tuner & TUNER_TYPE_MASK) < 4) { 1257 1242 if (snd_tea575x_init(&chip->tea)) { 1258 1243 snd_printk(KERN_ERR "TEA575x radio not found\n"); 1244 + snd_fm801_free(chip); 1259 1245 return -ENODEV; 1260 1246 } 1261 1247 } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { ··· 1303 1287 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); 1304 1288 if (err < 0) 1305 1289 return err; 1306 - if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) { 1290 + if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip)) < 0) { 1307 1291 snd_card_free(card); 1308 1292 return err; 1309 1293 }