Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville...
authorDavid S. Miller <davem@davemloft.net>
Fri, 4 Nov 2011 21:14:34 +0000 (17:14 -0400)
committerDavid S. Miller <davem@davemloft.net>
Fri, 4 Nov 2011 21:14:34 +0000 (17:14 -0400)
318 files changed:
Documentation/CodingStyle
Documentation/DocBook/media/v4l/compat.xml
Documentation/DocBook/media/v4l/controls.xml
Documentation/DocBook/media/v4l/io.xml
Documentation/DocBook/media/v4l/v4l2.xml
Documentation/DocBook/media/v4l/vidioc-create-bufs.xml [new file with mode: 0644]
Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml [new file with mode: 0644]
Documentation/block/switching-sched.txt
Documentation/cgroups/cgroups.txt
Documentation/devicetree/bindings/ata/calxeda-sata.txt [new file with mode: 0644]
Documentation/filesystems/hfs.txt
Documentation/filesystems/inotify.txt
Documentation/hwmon/w83627ehf
Documentation/laptops/thinkpad-acpi.txt
Documentation/leds/leds-class.txt
Documentation/serial/computone.txt
arch/arm/mach-pxa/pcm990-baseboard.c
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-mackerel.c
arch/ia64/include/asm/unistd.h
arch/ia64/kernel/entry.S
arch/sh/boards/mach-ap325rxa/setup.c
arch/sh/boards/mach-migor/setup.c
arch/tile/include/arch/Kbuild [new file with mode: 0644]
arch/tile/include/arch/abi.h
arch/tile/include/arch/opcode.h [moved from arch/tile/include/asm/opcode_constants.h with 62% similarity]
arch/tile/include/arch/opcode_tilegx.h [moved from arch/tile/include/asm/opcode_constants_64.h with 50% similarity]
arch/tile/include/arch/opcode_tilepro.h [new file with mode: 0644]
arch/tile/include/asm/Kbuild
arch/tile/include/asm/opcode-tile_32.h [deleted file]
arch/tile/include/asm/opcode-tile_64.h [deleted file]
arch/tile/include/asm/opcode_constants_32.h [deleted file]
arch/tile/include/asm/sigcontext.h
arch/tile/include/asm/tile-desc.h [moved from arch/tile/include/asm/opcode-tile.h with 56% similarity]
arch/tile/include/asm/tile-desc_32.h [new file with mode: 0644]
arch/tile/include/asm/tile-desc_64.h [new file with mode: 0644]
arch/tile/kernel/backtrace.c
arch/tile/kernel/module.c
arch/tile/kernel/single_step.c
arch/tile/kernel/tile-desc_32.c
arch/tile/kernel/tile-desc_64.c
arch/tile/kernel/traps.c
arch/tile/lib/exports.c
drivers/ata/ahci_platform.c
drivers/dma/ipu/ipu_idmac.c
drivers/hwmon/Kconfig
drivers/hwmon/ad7414.c
drivers/hwmon/ad7418.c
drivers/hwmon/ads1015.c
drivers/hwmon/ads7828.c
drivers/hwmon/asb100.c
drivers/hwmon/ds1621.c
drivers/hwmon/ds620.c
drivers/hwmon/gl518sm.c
drivers/hwmon/gl520sm.c
drivers/hwmon/ibmaem.c
drivers/hwmon/jc42.c
drivers/hwmon/lm73.c
drivers/hwmon/lm75.c
drivers/hwmon/lm77.c
drivers/hwmon/lm90.c
drivers/hwmon/lm92.c
drivers/hwmon/max16065.c
drivers/hwmon/sht21.c
drivers/hwmon/smm665.c
drivers/hwmon/smsc47b397.c
drivers/hwmon/tmp102.c
drivers/hwmon/w83627ehf.c
drivers/hwmon/w83781d.c
drivers/infiniband/hw/mthca/mthca_mr.c
drivers/infiniband/hw/qib/qib_rc.c
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/media/dvb/ddbridge/Makefile
drivers/media/dvb/dvb-usb/Makefile
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
drivers/media/dvb/dvb-usb/it913x.c
drivers/media/dvb/dvb-usb/mxl111sf-demod.c [new file with mode: 0644]
drivers/media/dvb/dvb-usb/mxl111sf-demod.h [new file with mode: 0644]
drivers/media/dvb/dvb-usb/mxl111sf.c
drivers/media/dvb/dvb-usb/mxl111sf.h
drivers/media/dvb/ngene/Makefile
drivers/media/radio/radio-tea5764.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/atmel-isi.c
drivers/media/video/cx18/cx18-driver.c
drivers/media/video/cx25821/Kconfig [moved from drivers/staging/cx25821/Kconfig with 100% similarity]
drivers/media/video/cx25821/Makefile [moved from drivers/staging/cx25821/Makefile with 100% similarity]
drivers/media/video/cx25821/cx25821-alsa.c [moved from drivers/staging/cx25821/cx25821-alsa.c with 100% similarity]
drivers/media/video/cx25821/cx25821-audio-upstream.c [moved from drivers/staging/cx25821/cx25821-audio-upstream.c with 100% similarity]
drivers/media/video/cx25821/cx25821-audio-upstream.h [moved from drivers/staging/cx25821/cx25821-audio-upstream.h with 100% similarity]
drivers/media/video/cx25821/cx25821-audio.h [moved from drivers/staging/cx25821/cx25821-audio.h with 100% similarity]
drivers/media/video/cx25821/cx25821-biffuncs.h [moved from drivers/staging/cx25821/cx25821-biffuncs.h with 100% similarity]
drivers/media/video/cx25821/cx25821-cards.c [moved from drivers/staging/cx25821/cx25821-cards.c with 100% similarity]
drivers/media/video/cx25821/cx25821-core.c [moved from drivers/staging/cx25821/cx25821-core.c with 100% similarity]
drivers/media/video/cx25821/cx25821-gpio.c [moved from drivers/staging/cx25821/cx25821-gpio.c with 100% similarity]
drivers/media/video/cx25821/cx25821-i2c.c [moved from drivers/staging/cx25821/cx25821-i2c.c with 100% similarity]
drivers/media/video/cx25821/cx25821-medusa-defines.h [moved from drivers/staging/cx25821/cx25821-medusa-defines.h with 100% similarity]
drivers/media/video/cx25821/cx25821-medusa-reg.h [moved from drivers/staging/cx25821/cx25821-medusa-reg.h with 100% similarity]
drivers/media/video/cx25821/cx25821-medusa-video.c [moved from drivers/staging/cx25821/cx25821-medusa-video.c with 100% similarity]
drivers/media/video/cx25821/cx25821-medusa-video.h [moved from drivers/staging/cx25821/cx25821-medusa-video.h with 100% similarity]
drivers/media/video/cx25821/cx25821-reg.h [moved from drivers/staging/cx25821/cx25821-reg.h with 100% similarity]
drivers/media/video/cx25821/cx25821-sram.h [moved from drivers/staging/cx25821/cx25821-sram.h with 100% similarity]
drivers/media/video/cx25821/cx25821-video-upstream-ch2.c [moved from drivers/staging/cx25821/cx25821-video-upstream-ch2.c with 100% similarity]
drivers/media/video/cx25821/cx25821-video-upstream-ch2.h [moved from drivers/staging/cx25821/cx25821-video-upstream-ch2.h with 100% similarity]
drivers/media/video/cx25821/cx25821-video-upstream.c [moved from drivers/staging/cx25821/cx25821-video-upstream.c with 100% similarity]
drivers/media/video/cx25821/cx25821-video-upstream.h [moved from drivers/staging/cx25821/cx25821-video-upstream.h with 100% similarity]
drivers/media/video/cx25821/cx25821-video.c [moved from drivers/staging/cx25821/cx25821-video.c with 99% similarity]
drivers/media/video/cx25821/cx25821-video.h [moved from drivers/staging/cx25821/cx25821-video.h with 100% similarity]
drivers/media/video/cx25821/cx25821.h [moved from drivers/staging/cx25821/cx25821.h with 99% similarity]
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/imx074.c
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/marvell-ccic/mcam-core.c
drivers/media/video/mem2mem_testdev.c
drivers/media/video/mt9m001.c
drivers/media/video/mt9m111.c
drivers/media/video/mt9t031.c
drivers/media/video/mt9t112.c
drivers/media/video/mt9v022.c
drivers/media/video/mx1_camera.c
drivers/media/video/mx2_camera.c
drivers/media/video/mx3_camera.c
drivers/media/video/omap/omap_vout.c
drivers/media/video/omap1_camera.c
drivers/media/video/omap3isp/isp.c
drivers/media/video/omap3isp/ispccdc.c
drivers/media/video/omap3isp/ispccp2.c
drivers/media/video/omap3isp/ispcsi2.c
drivers/media/video/omap3isp/isph3a_aewb.c
drivers/media/video/omap3isp/isph3a_af.c
drivers/media/video/omap3isp/isphist.c
drivers/media/video/omap3isp/isppreview.c
drivers/media/video/omap3isp/isppreview.h
drivers/media/video/omap3isp/ispreg.h
drivers/media/video/omap3isp/ispresizer.c
drivers/media/video/omap3isp/ispstat.c
drivers/media/video/omap3isp/ispstat.h
drivers/media/video/omap3isp/ispvideo.c
drivers/media/video/omap3isp/ispvideo.h
drivers/media/video/ov2640.c
drivers/media/video/ov5642.c
drivers/media/video/ov6650.c
drivers/media/video/ov772x.c
drivers/media/video/ov9640.c
drivers/media/video/ov9640.h
drivers/media/video/ov9740.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/pxa_camera.c
drivers/media/video/rj54n1cb0c.c
drivers/media/video/s5k6aa.c [new file with mode: 0644]
drivers/media/video/s5p-fimc/fimc-capture.c
drivers/media/video/s5p-fimc/fimc-core.c
drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
drivers/media/video/s5p-mfc/s5p_mfc_dec.c
drivers/media/video/s5p-mfc/s5p_mfc_enc.c
drivers/media/video/s5p-tv/mixer_video.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/sh_mobile_csi2.c
drivers/media/video/soc_camera.c
drivers/media/video/soc_camera_platform.c
drivers/media/video/soc_mediabus.c
drivers/media/video/tw9910.c
drivers/media/video/v4l2-compat-ioctl32.c
drivers/media/video/v4l2-ctrls.c
drivers/media/video/v4l2-device.c
drivers/media/video/v4l2-ioctl.c
drivers/media/video/videobuf2-core.c
drivers/media/video/vivi.c
drivers/of/platform.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/cx25821/README [deleted file]
drivers/staging/media/Kconfig [new file with mode: 0644]
drivers/staging/media/Makefile [new file with mode: 0644]
drivers/staging/media/as102/Kconfig [new file with mode: 0644]
drivers/staging/media/as102/Makefile [new file with mode: 0644]
drivers/staging/media/as102/as102_drv.c [new file with mode: 0644]
drivers/staging/media/as102/as102_drv.h [new file with mode: 0644]
drivers/staging/media/as102/as102_fe.c [new file with mode: 0644]
drivers/staging/media/as102/as102_fw.c [new file with mode: 0644]
drivers/staging/media/as102/as102_fw.h [new file with mode: 0644]
drivers/staging/media/as102/as102_usb_drv.c [new file with mode: 0644]
drivers/staging/media/as102/as102_usb_drv.h [new file with mode: 0644]
drivers/staging/media/as102/as10x_cmd.c [new file with mode: 0644]
drivers/staging/media/as102/as10x_cmd.h [new file with mode: 0644]
drivers/staging/media/as102/as10x_cmd_cfg.c [new file with mode: 0644]
drivers/staging/media/as102/as10x_cmd_stream.c [new file with mode: 0644]
drivers/staging/media/as102/as10x_handle.h [new file with mode: 0644]
drivers/staging/media/as102/as10x_types.h [new file with mode: 0644]
drivers/staging/media/cxd2099/Kconfig [moved from drivers/staging/cxd2099/Kconfig with 100% similarity]
drivers/staging/media/cxd2099/Makefile [moved from drivers/staging/cxd2099/Makefile with 100% similarity]
drivers/staging/media/cxd2099/TODO [moved from drivers/staging/cxd2099/TODO with 100% similarity]
drivers/staging/media/cxd2099/cxd2099.c [moved from drivers/staging/cxd2099/cxd2099.c with 100% similarity]
drivers/staging/media/cxd2099/cxd2099.h [moved from drivers/staging/cxd2099/cxd2099.h with 100% similarity]
drivers/staging/media/dt3155v4l/Kconfig [moved from drivers/staging/dt3155v4l/Kconfig with 100% similarity]
drivers/staging/media/dt3155v4l/Makefile [moved from drivers/staging/dt3155v4l/Makefile with 100% similarity]
drivers/staging/media/dt3155v4l/dt3155v4l.c [moved from drivers/staging/dt3155v4l/dt3155v4l.c with 100% similarity]
drivers/staging/media/dt3155v4l/dt3155v4l.h [moved from drivers/staging/dt3155v4l/dt3155v4l.h with 100% similarity]
drivers/staging/media/easycap/Kconfig [moved from drivers/staging/easycap/Kconfig with 100% similarity]
drivers/staging/media/easycap/Makefile [moved from drivers/staging/easycap/Makefile with 100% similarity]
drivers/staging/media/easycap/README [moved from drivers/staging/easycap/README with 100% similarity]
drivers/staging/media/easycap/easycap.h [moved from drivers/staging/easycap/easycap.h with 100% similarity]
drivers/staging/media/easycap/easycap_ioctl.c [moved from drivers/staging/easycap/easycap_ioctl.c with 100% similarity]
drivers/staging/media/easycap/easycap_low.c [moved from drivers/staging/easycap/easycap_low.c with 100% similarity]
drivers/staging/media/easycap/easycap_main.c [moved from drivers/staging/easycap/easycap_main.c with 100% similarity]
drivers/staging/media/easycap/easycap_settings.c [moved from drivers/staging/easycap/easycap_settings.c with 100% similarity]
drivers/staging/media/easycap/easycap_sound.c [moved from drivers/staging/easycap/easycap_sound.c with 100% similarity]
drivers/staging/media/easycap/easycap_testcard.c [moved from drivers/staging/easycap/easycap_testcard.c with 100% similarity]
drivers/staging/media/go7007/Kconfig [moved from drivers/staging/go7007/Kconfig with 100% similarity]
drivers/staging/media/go7007/Makefile [moved from drivers/staging/go7007/Makefile with 100% similarity]
drivers/staging/media/go7007/README [moved from drivers/staging/go7007/README with 100% similarity]
drivers/staging/media/go7007/go7007-driver.c [moved from drivers/staging/go7007/go7007-driver.c with 100% similarity]
drivers/staging/media/go7007/go7007-fw.c [moved from drivers/staging/go7007/go7007-fw.c with 100% similarity]
drivers/staging/media/go7007/go7007-i2c.c [moved from drivers/staging/go7007/go7007-i2c.c with 100% similarity]
drivers/staging/media/go7007/go7007-priv.h [moved from drivers/staging/go7007/go7007-priv.h with 100% similarity]
drivers/staging/media/go7007/go7007-usb.c [moved from drivers/staging/go7007/go7007-usb.c with 100% similarity]
drivers/staging/media/go7007/go7007-v4l2.c [moved from drivers/staging/go7007/go7007-v4l2.c with 100% similarity]
drivers/staging/media/go7007/go7007.h [moved from drivers/staging/go7007/go7007.h with 100% similarity]
drivers/staging/media/go7007/go7007.txt [moved from drivers/staging/go7007/go7007.txt with 100% similarity]
drivers/staging/media/go7007/s2250-board.c [moved from drivers/staging/go7007/s2250-board.c with 100% similarity]
drivers/staging/media/go7007/s2250-loader.c [moved from drivers/staging/go7007/s2250-loader.c with 100% similarity]
drivers/staging/media/go7007/s2250-loader.h [moved from drivers/staging/go7007/s2250-loader.h with 100% similarity]
drivers/staging/media/go7007/saa7134-go7007.c [moved from drivers/staging/go7007/saa7134-go7007.c with 100% similarity]
drivers/staging/media/go7007/snd-go7007.c [moved from drivers/staging/go7007/snd-go7007.c with 100% similarity]
drivers/staging/media/go7007/wis-i2c.h [moved from drivers/staging/go7007/wis-i2c.h with 100% similarity]
drivers/staging/media/go7007/wis-ov7640.c [moved from drivers/staging/go7007/wis-ov7640.c with 100% similarity]
drivers/staging/media/go7007/wis-saa7113.c [moved from drivers/staging/go7007/wis-saa7113.c with 100% similarity]
drivers/staging/media/go7007/wis-saa7115.c [moved from drivers/staging/go7007/wis-saa7115.c with 100% similarity]
drivers/staging/media/go7007/wis-sony-tuner.c [moved from drivers/staging/go7007/wis-sony-tuner.c with 100% similarity]
drivers/staging/media/go7007/wis-tw2804.c [moved from drivers/staging/go7007/wis-tw2804.c with 100% similarity]
drivers/staging/media/go7007/wis-tw9903.c [moved from drivers/staging/go7007/wis-tw9903.c with 100% similarity]
drivers/staging/media/go7007/wis-uda1342.c [moved from drivers/staging/go7007/wis-uda1342.c with 100% similarity]
drivers/staging/media/lirc/Kconfig [moved from drivers/staging/lirc/Kconfig with 100% similarity]
drivers/staging/media/lirc/Makefile [moved from drivers/staging/lirc/Makefile with 100% similarity]
drivers/staging/media/lirc/TODO [moved from drivers/staging/lirc/TODO with 100% similarity]
drivers/staging/media/lirc/TODO.lirc_zilog [moved from drivers/staging/lirc/TODO.lirc_zilog with 100% similarity]
drivers/staging/media/lirc/lirc_bt829.c [moved from drivers/staging/lirc/lirc_bt829.c with 100% similarity]
drivers/staging/media/lirc/lirc_ene0100.h [moved from drivers/staging/lirc/lirc_ene0100.h with 100% similarity]
drivers/staging/media/lirc/lirc_igorplugusb.c [moved from drivers/staging/lirc/lirc_igorplugusb.c with 100% similarity]
drivers/staging/media/lirc/lirc_imon.c [moved from drivers/staging/lirc/lirc_imon.c with 100% similarity]
drivers/staging/media/lirc/lirc_parallel.c [moved from drivers/staging/lirc/lirc_parallel.c with 100% similarity]
drivers/staging/media/lirc/lirc_parallel.h [moved from drivers/staging/lirc/lirc_parallel.h with 100% similarity]
drivers/staging/media/lirc/lirc_sasem.c [moved from drivers/staging/lirc/lirc_sasem.c with 100% similarity]
drivers/staging/media/lirc/lirc_serial.c [moved from drivers/staging/lirc/lirc_serial.c with 100% similarity]
drivers/staging/media/lirc/lirc_sir.c [moved from drivers/staging/lirc/lirc_sir.c with 100% similarity]
drivers/staging/media/lirc/lirc_ttusbir.c [moved from drivers/staging/lirc/lirc_ttusbir.c with 100% similarity]
drivers/staging/media/lirc/lirc_zilog.c [moved from drivers/staging/lirc/lirc_zilog.c with 100% similarity]
drivers/staging/media/solo6x10/Kconfig [moved from drivers/staging/solo6x10/Kconfig with 100% similarity]
drivers/staging/media/solo6x10/Makefile [moved from drivers/staging/solo6x10/Makefile with 100% similarity]
drivers/staging/media/solo6x10/TODO [moved from drivers/staging/solo6x10/TODO with 100% similarity]
drivers/staging/media/solo6x10/core.c [moved from drivers/staging/solo6x10/core.c with 100% similarity]
drivers/staging/media/solo6x10/disp.c [moved from drivers/staging/solo6x10/disp.c with 100% similarity]
drivers/staging/media/solo6x10/enc.c [moved from drivers/staging/solo6x10/enc.c with 100% similarity]
drivers/staging/media/solo6x10/g723.c [moved from drivers/staging/solo6x10/g723.c with 100% similarity]
drivers/staging/media/solo6x10/gpio.c [moved from drivers/staging/solo6x10/gpio.c with 100% similarity]
drivers/staging/media/solo6x10/i2c.c [moved from drivers/staging/solo6x10/i2c.c with 100% similarity]
drivers/staging/media/solo6x10/jpeg.h [moved from drivers/staging/solo6x10/jpeg.h with 100% similarity]
drivers/staging/media/solo6x10/offsets.h [moved from drivers/staging/solo6x10/offsets.h with 100% similarity]
drivers/staging/media/solo6x10/osd-font.h [moved from drivers/staging/solo6x10/osd-font.h with 100% similarity]
drivers/staging/media/solo6x10/p2m.c [moved from drivers/staging/solo6x10/p2m.c with 100% similarity]
drivers/staging/media/solo6x10/registers.h [moved from drivers/staging/solo6x10/registers.h with 100% similarity]
drivers/staging/media/solo6x10/solo6x10.h [moved from drivers/staging/solo6x10/solo6x10.h with 100% similarity]
drivers/staging/media/solo6x10/tw28.c [moved from drivers/staging/solo6x10/tw28.c with 100% similarity]
drivers/staging/media/solo6x10/tw28.h [moved from drivers/staging/solo6x10/tw28.h with 100% similarity]
drivers/staging/media/solo6x10/v4l2-enc.c [moved from drivers/staging/solo6x10/v4l2-enc.c with 100% similarity]
drivers/staging/media/solo6x10/v4l2.c [moved from drivers/staging/solo6x10/v4l2.c with 100% similarity]
fs/exofs/Kconfig
fs/nfs/callback_xdr.c
fs/nfs/file.c
fs/nfs/nfs4filelayout.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/objlayout/objio_osd.c
fs/nfs/objlayout/objlayout.c
fs/nfs/objlayout/objlayout.h
fs/nfs/pagelist.c
fs/nfs/pnfs.c
fs/nfs/write.c
fs/nfsd/nfssvc.c
include/linux/nfs_fs.h
include/linux/of.h
include/linux/sunrpc/clnt.h
include/linux/sunrpc/svc.h
include/linux/videodev2.h
include/media/ov772x.h
include/media/s5k6aa.h [new file with mode: 0644]
include/media/soc_camera.h
include/media/soc_camera_platform.h
include/media/soc_mediabus.h
include/media/v4l2-ioctl.h
include/media/v4l2-subdev.h
include/media/videobuf2-core.h
net/sunrpc/auth_unix.c
net/sunrpc/rpcb_clnt.c
net/sunrpc/sunrpc_syms.c
net/sunrpc/svc.c
sound/core/hwdep.c
sound/pci/hda/hda_hwdep.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/pci/intel8x0.c
sound/pci/rme9652/hdsp.c
sound/pci/rme9652/hdspm.c
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/wm5100.c
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8940.c
sound/soc/codecs/wm8962.c

index c940239..2b90d32 100644 (file)
@@ -166,8 +166,8 @@ if (condition)
 else
        do_that();
 
-This does not apply if one branch of a conditional statement is a single
-statement. Use braces in both branches.
+This does not apply if only one branch of a conditional statement is a single
+statement; in the latter case use braces in both branches:
 
 if (condition) {
        do_this();
index 91410b6..b68698f 100644 (file)
@@ -2486,6 +2486,9 @@ ioctls.</para>
         <listitem>
          <para>Flash API. <xref linkend="flash-controls" /></para>
         </listitem>
+        <listitem>
+         <para>&VIDIOC-CREATE-BUFS; and &VIDIOC-PREPARE-BUF; ioctls.</para>
+        </listitem>
       </itemizedlist>
     </section>
 
index 23fdf79..3bc5ee8 100644 (file)
@@ -232,8 +232,9 @@ control is deprecated. New drivers and applications should use the
            <entry>Enables a power line frequency filter to avoid
 flicker. Possible values for <constant>enum v4l2_power_line_frequency</constant> are:
 <constant>V4L2_CID_POWER_LINE_FREQUENCY_DISABLED</constant> (0),
-<constant>V4L2_CID_POWER_LINE_FREQUENCY_50HZ</constant> (1) and
-<constant>V4L2_CID_POWER_LINE_FREQUENCY_60HZ</constant> (2).</entry>
+<constant>V4L2_CID_POWER_LINE_FREQUENCY_50HZ</constant> (1),
+<constant>V4L2_CID_POWER_LINE_FREQUENCY_60HZ</constant> (2) and
+<constant>V4L2_CID_POWER_LINE_FREQUENCY_AUTO</constant> (3).</entry>
          </row>
          <row>
            <entry><constant>V4L2_CID_HUE_AUTO</constant></entry>
index c57d1ec..3f47df1 100644 (file)
@@ -927,6 +927,33 @@ ioctl is called.</entry>
 Applications set or clear this flag before calling the
 <constant>VIDIOC_QBUF</constant> ioctl.</entry>
          </row>
+         <row>
+           <entry><constant>V4L2_BUF_FLAG_PREPARED</constant></entry>
+           <entry>0x0400</entry>
+           <entry>The buffer has been prepared for I/O and can be queued by the
+application. Drivers set or clear this flag when the
+<link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
+         linkend="vidioc-qbuf">VIDIOC_PREPARE_BUF</link>, <link
+         linkend="vidioc-qbuf">VIDIOC_QBUF</link> or <link
+         linkend="vidioc-qbuf">VIDIOC_DQBUF</link> ioctl is called.</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
+           <entry>0x0400</entry>
+           <entry>Caches do not have to be invalidated for this buffer.
+Typically applications shall use this flag if the data captured in the buffer
+is not going to be touched by the CPU, instead the buffer will, probably, be
+passed on to a DMA-capable hardware unit for further processing or output.
+</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
+           <entry>0x0800</entry>
+           <entry>Caches do not have to be cleaned for this buffer.
+Typically applications shall use this flag for output buffers if the data
+in this buffer has not been created by the CPU but by some DMA-capable unit,
+in which case caches have not been used.</entry>
+         </row>
        </tbody>
       </tgroup>
     </table>
index 40132c2..2ab365c 100644 (file)
@@ -469,6 +469,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-close;
     &sub-ioctl;
     <!-- All ioctls go here. -->
+    &sub-create-bufs;
     &sub-cropcap;
     &sub-dbg-g-chip-ident;
     &sub-dbg-g-register;
@@ -511,6 +512,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-queryctrl;
     &sub-query-dv-preset;
     &sub-querystd;
+    &sub-prepare-buf;
     &sub-reqbufs;
     &sub-s-hw-freq-seek;
     &sub-streamon;
diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml
new file mode 100644 (file)
index 0000000..73ae8a6
--- /dev/null
@@ -0,0 +1,139 @@
+<refentry id="vidioc-create-bufs">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_CREATE_BUFS</refname>
+    <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+       <funcdef>int <function>ioctl</function></funcdef>
+       <paramdef>int <parameter>fd</parameter></paramdef>
+       <paramdef>int <parameter>request</parameter></paramdef>
+       <paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+       <term><parameter>fd</parameter></term>
+       <listitem>
+         <para>&fd;</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>request</parameter></term>
+       <listitem>
+         <para>VIDIOC_CREATE_BUFS</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>argp</parameter></term>
+       <listitem>
+         <para></para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl is used to create buffers for <link linkend="mmap">memory
+mapped</link> or <link linkend="userp">user pointer</link>
+I/O. It can be used as an alternative or in addition to the
+<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
+is required. This ioctl can be called multiple times to create buffers of
+different sizes.</para>
+
+    <para>To allocate device buffers applications initialize relevant fields of
+the <structname>v4l2_create_buffers</structname> structure. They set the
+<structfield>type</structfield> field in the
+<structname>v4l2_format</structname> structure, embedded in this
+structure, to the respective stream or buffer type.
+<structfield>count</structfield> must be set to the number of required buffers.
+<structfield>memory</structfield> specifies the required I/O method. The
+<structfield>format</structfield> field shall typically be filled in using
+either the <constant>VIDIOC_TRY_FMT</constant> or
+<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
+<structfield>sizeimage</structfield> fields to fit their specific needs. The
+<structfield>reserved</structfield> array must be zeroed.</para>
+
+    <para>When the ioctl is called with a pointer to this structure the driver
+will attempt to allocate up to the requested number of buffers and store the
+actual number allocated and the starting index in the
+<structfield>count</structfield> and the <structfield>index</structfield> fields
+respectively. On return <structfield>count</structfield> can be smaller than
+the number requested. The driver may also increase buffer sizes if required,
+however, it will not update <structfield>sizeimage</structfield> field values.
+The user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
+information.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-create-buffers">
+      <title>struct <structname>v4l2_create_buffers</structname></title>
+      <tgroup cols="3">
+       &cs-str;
+       <tbody valign="top">
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>index</structfield></entry>
+           <entry>The starting buffer index, returned by the driver.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>count</structfield></entry>
+           <entry>The number of buffers requested or granted.</entry>
+         </row>
+         <row>
+           <entry>&v4l2-memory;</entry>
+           <entry><structfield>memory</structfield></entry>
+           <entry>Applications set this field to
+<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
+         </row>
+         <row>
+           <entry>&v4l2-format;</entry>
+           <entry><structfield>format</structfield></entry>
+           <entry>Filled in by the application, preserved by the driver.</entry>
+         </row>
+         <row>
+           <entry>__u32</entry>
+           <entry><structfield>reserved</structfield>[8]</entry>
+           <entry>A place holder for future extensions.</entry>
+         </row>
+       </tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+       <term><errorcode>ENOMEM</errorcode></term>
+       <listitem>
+         <para>No memory to allocate buffers for <link linkend="mmap">memory
+mapped</link> I/O.</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><errorcode>EINVAL</errorcode></term>
+       <listitem>
+         <para>The buffer type (<structfield>type</structfield> field) or the
+requested I/O method (<structfield>memory</structfield>) is not
+supported.</para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
new file mode 100644 (file)
index 0000000..7bde698
--- /dev/null
@@ -0,0 +1,88 @@
+<refentry id="vidioc-prepare-buf">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_PREPARE_BUF</refname>
+    <refpurpose>Prepare a buffer for I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+       <funcdef>int <function>ioctl</function></funcdef>
+       <paramdef>int <parameter>fd</parameter></paramdef>
+       <paramdef>int <parameter>request</parameter></paramdef>
+       <paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+       <term><parameter>fd</parameter></term>
+       <listitem>
+         <para>&fd;</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>request</parameter></term>
+       <listitem>
+         <para>VIDIOC_PREPARE_BUF</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><parameter>argp</parameter></term>
+       <listitem>
+         <para></para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Applications can optionally call the
+<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
+to the driver before actually enqueuing it, using the
+<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
+Such preparations may include cache invalidation or cleaning. Performing them
+in advance saves time during the actual I/O. In case such cache operations are
+not required, the application can use one of
+<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
+<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
+step.</para>
+
+    <para>The <structname>v4l2_buffer</structname> structure is
+specified in <xref linkend="buffer" />.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+       <term><errorcode>EBUSY</errorcode></term>
+       <listitem>
+         <para>File I/O is in progress.</para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term><errorcode>EINVAL</errorcode></term>
+       <listitem>
+         <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds,
+or no buffers have been allocated yet, or the
+<structfield>userptr</structfield> or
+<structfield>length</structfield> are invalid.</para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
index 71cfbdc..3b2612e 100644 (file)
@@ -1,6 +1,6 @@
 To choose IO schedulers at boot time, use the argument 'elevator=deadline'.
-'noop', 'as' and 'cfq' (the default) are also available. IO schedulers are
-assigned globally at boot time only presently.
+'noop' and 'cfq' (the default) are also available. IO schedulers are assigned
+globally at boot time only presently.
 
 Each io queue has a set of io scheduler tunables associated with it. These
 tunables control how the io scheduler works. You can find these entries
index cd67e90..9c452ef 100644 (file)
@@ -454,8 +454,8 @@ mounted hierarchy, to remove a task from its current cgroup you must
 move it into a new cgroup (possibly the root cgroup) by writing to the
 new cgroup's tasks file.
 
-Note: If the ns cgroup is active, moving a process to another cgroup can
-fail.
+Note: Due to some restrictions enforced by some cgroup subsystems, moving
+a process to another cgroup can fail.
 
 2.3 Mounting hierarchies by name
 --------------------------------
diff --git a/Documentation/devicetree/bindings/ata/calxeda-sata.txt b/Documentation/devicetree/bindings/ata/calxeda-sata.txt
new file mode 100644 (file)
index 0000000..79caa56
--- /dev/null
@@ -0,0 +1,17 @@
+* Calxeda SATA Controller
+
+SATA nodes are defined to describe on-chip Serial ATA controllers.
+Each SATA controller should have its own node.
+
+Required properties:
+- compatible        : compatible list, contains "calxeda,hb-ahci"
+- interrupts        : <interrupt mapping for SATA IRQ>
+- reg               : <registers mapping>
+
+Example:
+        sata@ffe08000 {
+               compatible = "calxeda,hb-ahci";
+                reg = <0xffe08000 0x1000>;
+                interrupts = <115>;
+        };
+
index bd0fa77..d096df6 100644 (file)
@@ -1,3 +1,4 @@
+Note: This filesystem doesn't have a maintainer.
 
 Macintosh HFS Filesystem for Linux
 ==================================
@@ -76,8 +77,6 @@ hformat that can be used to create HFS filesystem. See
 Credits
 =======
 
-The HFS drivers was written by Paul H. Hargrovea (hargrove@sccm.Stanford.EDU)
-and is now maintained by Roman Zippel (roman@ardistech.com) at Ardis
-Technologies.
-Roman rewrote large parts of the code and brought in btree routines derived
-from Brad Boyer's hfsplus driver (also maintained by Roman now).
+The HFS drivers was written by Paul H. Hargrovea (hargrove@sccm.Stanford.EDU).
+Roman Zippel (roman@ardistech.com) rewrote large parts of the code and brought
+in btree routines derived from Brad Boyer's hfsplus driver.
index 59a919f..cfd0271 100644 (file)
@@ -194,7 +194,8 @@ associated with the inotify_handle, and on which events are queued.
 Each watch is associated with an inotify_watch structure.  Watches are chained
 off of each associated inotify_handle and each associated inode.
 
-See fs/inotify.c and fs/inotify_user.c for the locking and lifetime rules.
+See fs/notify/inotify/inotify_fsnotify.c and fs/notify/inotify/inotify_user.c
+for the locking and lifetime rules.
 
 
 (vi) Rationale
index 76ffef9..3f44dbd 100644 (file)
@@ -14,6 +14,10 @@ Supported chips:
     Prefix: 'w83627dhg'
     Addresses scanned: ISA address retrieved from Super I/O registers
     Datasheet: not available
+  * Winbond W83627UHG
+    Prefix: 'w83627uhg'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet: available from www.nuvoton.com
   * Winbond W83667HG
     Prefix: 'w83667hg'
     Addresses scanned: ISA address retrieved from Super I/O registers
@@ -42,14 +46,13 @@ Description
 -----------
 
 This driver implements support for the Winbond W83627EHF, W83627EHG,
-W83627DHG, W83627DHG-P, W83667HG, W83667HG-B, W83667HG-I (NCT6775F),
-and NCT6776F super I/O chips. We will refer to them collectively as
-Winbond chips.
-
-The chips implement three temperature sensors (up to four for 667HG-B, and nine
-for NCT6775F and NCT6776F), five fan rotation speed sensors, ten analog voltage
-sensors (only nine for the 627DHG), one VID (6 pins for the 627EHF/EHG, 8 pins
-for the 627DHG and 667HG), alarms with beep warnings (control unimplemented),
+W83627DHG, W83627DHG-P, W83627UHG, W83667HG, W83667HG-B, W83667HG-I
+(NCT6775F), and NCT6776F super I/O chips. We will refer to them collectively
+as Winbond chips.
+
+The chips implement 2 to 4 temperature sensors (9 for NCT6775F and NCT6776F),
+2 to 5 fan rotation speed sensors, 8 to 10 analog voltage sensors, one VID
+(except for 627UHG), alarms with beep warnings (control unimplemented),
 and some automatic fan regulation strategies (plus manual fan control mode).
 
 The temperature sensor sources on W82677HG-B, NCT6775F, and NCT6776F are
@@ -86,17 +89,16 @@ follows:
 
 temp1 -> pwm1
 temp2 -> pwm2
-temp3 -> pwm3
+temp3 -> pwm3 (not on 627UHG)
 prog  -> pwm4 (not on 667HG and 667HG-B; the programmable setting is not
               supported by the driver)
 
 /sys files
 ----------
 
-name - this is a standard hwmon device entry. For the W83627EHF and W83627EHG,
-       it is set to "w83627ehf", for the W83627DHG it is set to "w83627dhg",
-       for the W83667HG and W83667HG-B it is set to "w83667hg", for NCT6775F it
-       is set to "nct6775", and for NCT6776F it is set to "nct6776".
+name - this is a standard hwmon device entry, it contains the name of
+       the device (see the prefix in the list of supported devices at
+       the top of this file)
 
 pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range:
           0 (stop) to 255 (full)
index 3ff0dad..9d66682 100644 (file)
@@ -411,9 +411,9 @@ event       code    Key             Notes
 
 0x1004 0x03    FN+F4           Sleep button (ACPI sleep button
                                semantics, i.e. sleep-to-RAM).
-                               It is always generate some kind
+                               It always generates some kind
                                of event, either the hot key
-                               event or a ACPI sleep button
+                               event or an ACPI sleep button
                                event. The firmware may
                                refuse to generate further FN+F4
                                key presses until a S3 or S4 ACPI
index 4996586..79699c2 100644 (file)
@@ -61,8 +61,8 @@ Hardware accelerated blink of LEDs
 Some LEDs can be programmed to blink without any CPU interaction. To
 support this feature, a LED driver can optionally implement the
 blink_set() function (see <linux/leds.h>). To set an LED to blinking,
-however, it is better to use use the API function led_blink_set(),
-as it will check and implement software fallback if necessary.
+however, it is better to use the API function led_blink_set(), as it
+will check and implement software fallback if necessary.
 
 To turn off blinking again, use the API function led_brightness_set()
 as that will not just set the LED brightness but also stop any software
index 60a6f65..39ddcdb 100644 (file)
@@ -20,8 +20,6 @@ Version: 1.2.14
 Date: 11/01/2001
 Historical Author: Andrew Manison <amanison@america.net>
 Primary Author: Doug McNash
-Support: support@computone.com
-Fixes and Updates: Mike Warfield <mhw@wittsend.com>
 
 This file assumes that you are using the Computone drivers which are
 integrated into the kernel sources.  For updating the drivers or installing
index 9a9c539..6d38c65 100644 (file)
@@ -394,9 +394,9 @@ static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
        }
 
        if (flags & SOCAM_DATAWIDTH_8)
-               gpio_set_value(gpio_bus_switch, 1);
+               gpio_set_value_cansleep(gpio_bus_switch, 1);
        else
-               gpio_set_value(gpio_bus_switch, 0);
+               gpio_set_value_cansleep(gpio_bus_switch, 0);
 
        return 0;
 }
index 5b7edad..f9f66c2 100644 (file)
@@ -933,7 +933,7 @@ static struct platform_device ap4evb_camera = {
 static struct sh_csi2_client_config csi2_clients[] = {
        {
                .phy            = SH_CSI2_PHY_MAIN,
-               .lanes          = 3,
+               .lanes          = 0,            /* default: 2 lanes */
                .channel        = 0,
                .pdev           = &ap4evb_camera,
        },
index 3689ad2..6820423 100644 (file)
@@ -1223,9 +1223,10 @@ static struct soc_camera_platform_info camera_info = {
                .width = 640,
                .height = 480,
        },
-       .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
-       SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
-       SOCAM_DATA_ACTIVE_HIGH,
+       .mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+       V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+       V4L2_MBUS_DATA_ACTIVE_HIGH,
+       .mbus_type = V4L2_MBUS_PARALLEL,
        .set_capture = camera_set_capture,
 };
 
index 7c928da..7617248 100644 (file)
 #define __NR_syncfs                    1329
 #define __NR_setns                     1330
 #define __NR_sendmmsg                  1331
+#define __NR_process_vm_readv          1332
+#define __NR_process_vm_writev         1333
 
 #ifdef __KERNEL__
 
 
-#define NR_syscalls                    308 /* length of syscall table */
+#define NR_syscalls                    310 /* length of syscall table */
 
 /*
  * The following defines stop scripts/checksyscalls.sh from complaining about
index 198c753..5b31d46 100644 (file)
@@ -1777,6 +1777,8 @@ sys_call_table:
        data8 sys_syncfs
        data8 sys_setns                         // 1330
        data8 sys_sendmmsg
+       data8 sys_process_vm_readv
+       data8 sys_process_vm_writev
 
        .org sys_call_table + 8*NR_syscalls     // guard against failures to increase NR_syscalls
 #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
index d362657..7030f4c 100644 (file)
@@ -345,9 +345,10 @@ static struct soc_camera_platform_info camera_info = {
                .width = 640,
                .height = 480,
        },
-       .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
-       SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
-       SOCAM_DATA_ACTIVE_HIGH,
+       .mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+       V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+       V4L2_MBUS_DATA_ACTIVE_HIGH,
+       .mbus_type = V4L2_MBUS_PARALLEL,
        .set_capture = camera_set_capture,
 };
 
@@ -501,8 +502,7 @@ static struct i2c_board_info ap325rxa_i2c_camera[] = {
 };
 
 static struct ov772x_camera_info ov7725_info = {
-       .flags          = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP | \
-                         OV772X_FLAG_8BIT,
+       .flags          = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
        .edgectrl       = OV772X_AUTO_EDGECTRL(0xf, 0),
 };
 
index 2d4c9c8..e4c8119 100644 (file)
@@ -448,9 +448,7 @@ static struct i2c_board_info migor_i2c_camera[] = {
        },
 };
 
-static struct ov772x_camera_info ov7725_info = {
-       .flags          = OV772X_FLAG_8BIT,
-};
+static struct ov772x_camera_info ov7725_info;
 
 static struct soc_camera_link ov7725_link = {
        .power          = ov7725_power,
diff --git a/arch/tile/include/arch/Kbuild b/arch/tile/include/arch/Kbuild
new file mode 100644 (file)
index 0000000..9c0ea24
--- /dev/null
@@ -0,0 +1,17 @@
+header-y += abi.h
+header-y += chip.h
+header-y += chip_tile64.h
+header-y += chip_tilegx.h
+header-y += chip_tilepro.h
+header-y += icache.h
+header-y += interrupts.h
+header-y += interrupts_32.h
+header-y += interrupts_64.h
+header-y += opcode.h
+header-y += opcode_tilegx.h
+header-y += opcode_tilepro.h
+header-y += sim.h
+header-y += sim_def.h
+header-y += spr_def.h
+header-y += spr_def_32.h
+header-y += spr_def_64.h
index 8affc76..c55a3d4 100644 (file)
 /**
  * @file
  *
- * ABI-related register definitions helpful when writing assembly code.
+ * ABI-related register definitions.
  */
 
 #ifndef __ARCH_ABI_H__
-#define __ARCH_ABI_H__
 
-#include <arch/chip.h>
+#if !defined __need_int_reg_t && !defined __DOXYGEN__
+# define __ARCH_ABI_H__
+# include <arch/chip.h>
+#endif
+
+/* Provide the basic machine types. */
+#ifndef __INT_REG_BITS
+
+/** Number of bits in a register. */
+#if defined __tilegx__
+# define __INT_REG_BITS 64
+#elif defined __tilepro__
+# define __INT_REG_BITS 32
+#elif !defined __need_int_reg_t
+# include <arch/chip.h>
+# define __INT_REG_BITS CHIP_WORD_SIZE()
+#else
+# error Unrecognized architecture with __need_int_reg_t
+#endif
+
+#if __INT_REG_BITS == 64
+
+#ifndef __ASSEMBLER__
+/** Unsigned type that can hold a register. */
+typedef unsigned long long __uint_reg_t;
+
+/** Signed type that can hold a register. */
+typedef long long __int_reg_t;
+#endif
+
+/** String prefix to use for printf(). */
+#define __INT_REG_FMT "ll"
+
+#else
+
+#ifndef __ASSEMBLER__
+/** Unsigned type that can hold a register. */
+typedef unsigned long __uint_reg_t;
+
+/** Signed type that can hold a register. */
+typedef long __int_reg_t;
+#endif
+
+/** String prefix to use for printf(). */
+#define __INT_REG_FMT "l"
+
+#endif
+#endif /* __INT_REG_BITS */
+
+
+#ifndef __need_int_reg_t
+
+
+#ifndef __ASSEMBLER__
+/** Unsigned type that can hold a register. */
+typedef __uint_reg_t uint_reg_t;
+
+/** Signed type that can hold a register. */
+typedef __int_reg_t int_reg_t;
+#endif
+
+/** String prefix to use for printf(). */
+#define INT_REG_FMT __INT_REG_FMT
+
+/** Number of bits in a register. */
+#define INT_REG_BITS __INT_REG_BITS
+
 
 /* Registers 0 - 55 are "normal", but some perform special roles. */
 
  * The ABI requires callers to allocate a caller state save area of
  * this many bytes at the bottom of each stack frame.
  */
-#define C_ABI_SAVE_AREA_SIZE (2 * (CHIP_WORD_SIZE() / 8))
+#define C_ABI_SAVE_AREA_SIZE (2 * (INT_REG_BITS / 8))
 
 /**
  * The operand to an 'info' opcode directing the backtracer to not
  */
 #define INFO_OP_CANNOT_BACKTRACE 2
 
-#ifndef __ASSEMBLER__
-#if CHIP_WORD_SIZE() > 32
 
-/** Unsigned type that can hold a register. */
-typedef unsigned long long uint_reg_t;
+#endif /* !__need_int_reg_t */
 
-/** Signed type that can hold a register. */
-typedef long long int_reg_t;
-
-/** String prefix to use for printf(). */
-#define INT_REG_FMT "ll"
-
-#elif !defined(__LP64__)   /* avoid confusion with LP64 cross-build tools */
-
-/** Unsigned type that can hold a register. */
-typedef unsigned long uint_reg_t;
-
-/** Signed type that can hold a register. */
-typedef long int_reg_t;
-
-/** String prefix to use for printf(). */
-#define INT_REG_FMT "l"
-
-#endif
-#endif /* __ASSEMBLER__ */
+/* Make sure we later can get all the definitions and declarations.  */
+#undef __need_int_reg_t
 
 #endif /* !__ARCH_ABI_H__ */
similarity index 62%
rename from arch/tile/include/asm/opcode_constants.h
rename to arch/tile/include/arch/opcode.h
index 37a9f29..92d1522 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
  *
  *   This program is free software; you can redistribute it and/or
  *   modify it under the terms of the GNU General Public License
  *   more details.
  */
 
-#ifndef _ASM_TILE_OPCODE_CONSTANTS_H
-#define _ASM_TILE_OPCODE_CONSTANTS_H
-
-#include <arch/chip.h>
-
-#if CHIP_WORD_SIZE() == 64
-#include <asm/opcode_constants_64.h>
+#if defined(__tilepro__)
+#include <arch/opcode_tilepro.h>
+#elif defined(__tilegx__)
+#include <arch/opcode_tilegx.h>
 #else
-#include <asm/opcode_constants_32.h>
+#error Unexpected Tilera chip type
 #endif
-
-#endif /* _ASM_TILE_OPCODE_CONSTANTS_H */
similarity index 50%
rename from arch/tile/include/asm/opcode_constants_64.h
rename to arch/tile/include/arch/opcode_tilegx.h
index 7101928..c14d02c 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* TILE-Gx opcode information.
+ *
  * Copyright 2011 Tilera Corporation. All Rights Reserved.
  *
  *   This program is free software; you can redistribute it and/or
  *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  *   NON INFRINGEMENT.  See the GNU General Public License for
  *   more details.
+ *
+ *
+ *
+ *
+ *
  */
 
-/* This file is machine-generated; DO NOT EDIT! */
+#ifndef __ARCH_OPCODE_H__
+#define __ARCH_OPCODE_H__
+
+#ifndef __ASSEMBLER__
+
+typedef unsigned long long tilegx_bundle_bits;
+
+/* These are the bits that determine if a bundle is in the X encoding. */
+#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
+
+enum
+{
+  /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
+  TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
+
+  /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
+  TILEGX_NUM_PIPELINE_ENCODINGS = 5,
+
+  /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */
+  TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
+
+  /* Instructions take this many bytes. */
+  TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,
+
+  /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */
+  TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
+
+  /* Bundles should be aligned modulo this number of bytes. */
+  TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =
+    (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
+
+  /* Number of registers (some are magic, such as network I/O). */
+  TILEGX_NUM_REGISTERS = 64,
+};
+
+/* Make a few "tile_" variables to simplify common code between
+   architectures.  */
+
+typedef tilegx_bundle_bits tile_bundle_bits;
+#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES
+#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
+#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
+  TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
+
+/* 64-bit pattern for a { bpt ; nop } bundle. */
+#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
+
+static __inline unsigned int
+get_BFEnd_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 24)) & 0xf);
+}
+
+static __inline unsigned int
+get_BFStart_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x3f);
+}
+
+static __inline unsigned int
+get_BrOff_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x0000003f) |
+         (((unsigned int)(n >> 37)) & 0x0001ffc0);
+}
+
+static __inline unsigned int
+get_BrType_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 54)) & 0x1f);
+}
+
+static __inline unsigned int
+get_Dest_Imm8_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x0000003f) |
+         (((unsigned int)(n >> 43)) & 0x000000c0);
+}
+
+static __inline unsigned int
+get_Dest_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Imm16_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm16_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 20)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 51)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_JumpOff_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x7ffffff);
+}
+
+static __inline unsigned int
+get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 58)) & 0x1);
+}
+
+static __inline unsigned int
+get_MF_Imm14_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 37)) & 0x3fff);
+}
+
+static __inline unsigned int
+get_MT_Imm14_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x0000003f) |
+         (((unsigned int)(n >> 37)) & 0x00003fc0);
+}
+
+static __inline unsigned int
+get_Mode(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 62)) & 0x3);
+}
+
+static __inline unsigned int
+get_Opcode_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 28)) & 0x7);
+}
+
+static __inline unsigned int
+get_Opcode_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 59)) & 0x7);
+}
+
+static __inline unsigned int
+get_Opcode_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 27)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 58)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y2(tilegx_bundle_bits n)
+{
+  return (((n >> 26)) & 0x00000001) |
+         (((unsigned int)(n >> 56)) & 0x00000002);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 49)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x3);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 49)) & 0x3);
+}
+
+static __inline unsigned int
+get_ShAmt_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_ShAmt_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 49)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x3);
+}
+
+static __inline unsigned int
+get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 49)) & 0x3);
+}
+
+static __inline unsigned int
+get_SrcA_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y2(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 20)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcBDest_Y2(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 51)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+
+static __inline int
+sign_extend(int n, int num_bits)
+{
+  int shift = (int)(sizeof(int) * 8 - num_bits);
+  return (n << shift) >> shift;
+}
+
+
+
+static __inline tilegx_bundle_bits
+create_BFEnd_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_BFOpcodeExtension_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xf) << 24);
+}
+
+static __inline tilegx_bundle_bits
+create_BFStart_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_BrOff_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
+         (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_BrType_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x1f)) << 54);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_Imm8_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
+         (((tilegx_bundle_bits)(n & 0x000000c0)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 0);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 0);
+}
+
+static __inline tilegx_bundle_bits
+create_Dest_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm16_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xffff) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm16_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0xffff)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8OpcodeExtension_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xff) << 20);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8OpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0xff)) << 51);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xff) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xff) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_Imm8_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_JumpOff_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31);
+}
+
+static __inline tilegx_bundle_bits
+create_JumpOpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x1)) << 58);
+}
+
+static __inline tilegx_bundle_bits
+create_MF_Imm14_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3fff)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_MT_Imm14_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
+         (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_Mode(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3)) << 62);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x7) << 28);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x7)) << 59);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xf) << 27);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0xf)) << 58);
+}
+
+static __inline tilegx_bundle_bits
+create_Opcode_Y2(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x00000001) << 26) |
+         (((tilegx_bundle_bits)(n & 0x00000002)) << 56);
+}
+
+static __inline tilegx_bundle_bits
+create_RRROpcodeExtension_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3ff) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_RRROpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
+}
+
+static __inline tilegx_bundle_bits
+create_RRROpcodeExtension_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_RRROpcodeExtension_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3)) << 49);
+}
+
+static __inline tilegx_bundle_bits
+create_ShAmt_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_ShAmt_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_ShAmt_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_ShAmt_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3ff) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
+}
+
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3) << 18);
+}
+
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3)) << 49);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 6);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 6);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcA_Y2(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 20);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcBDest_Y2(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 51);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcB_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcB_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcB_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_SrcB_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 12);
+}
+
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
+}
 
 
-#ifndef _TILE_OPCODE_CONSTANTS_H
-#define _TILE_OPCODE_CONSTANTS_H
 enum
 {
   ADDI_IMM8_OPCODE_X0 = 1,
@@ -606,4 +1399,7 @@ enum
   XOR_RRR_5_OPCODE_Y1 = 3
 };
 
-#endif /* !_TILE_OPCODE_CONSTANTS_H */
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __ARCH_OPCODE_H__ */
diff --git a/arch/tile/include/arch/opcode_tilepro.h b/arch/tile/include/arch/opcode_tilepro.h
new file mode 100644 (file)
index 0000000..71b763b
--- /dev/null
@@ -0,0 +1,1471 @@
+/* TILEPro opcode information.
+ *
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ *
+ *
+ *
+ *
+ */
+
+#ifndef __ARCH_OPCODE_H__
+#define __ARCH_OPCODE_H__
+
+#ifndef __ASSEMBLER__
+
+typedef unsigned long long tilepro_bundle_bits;
+
+/* This is the bit that determines if a bundle is in the Y encoding. */
+#define TILEPRO_BUNDLE_Y_ENCODING_MASK ((tilepro_bundle_bits)1 << 63)
+
+enum
+{
+  /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
+  TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
+
+  /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
+  TILEPRO_NUM_PIPELINE_ENCODINGS = 5,
+
+  /* Log base 2 of TILEPRO_BUNDLE_SIZE_IN_BYTES. */
+  TILEPRO_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
+
+  /* Instructions take this many bytes. */
+  TILEPRO_BUNDLE_SIZE_IN_BYTES = 1 << TILEPRO_LOG2_BUNDLE_SIZE_IN_BYTES,
+
+  /* Log base 2 of TILEPRO_BUNDLE_ALIGNMENT_IN_BYTES. */
+  TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
+
+  /* Bundles should be aligned modulo this number of bytes. */
+  TILEPRO_BUNDLE_ALIGNMENT_IN_BYTES =
+    (1 << TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
+
+  /* Log base 2 of TILEPRO_SN_INSTRUCTION_SIZE_IN_BYTES. */
+  TILEPRO_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES = 1,
+
+  /* Static network instructions take this many bytes. */
+  TILEPRO_SN_INSTRUCTION_SIZE_IN_BYTES =
+    (1 << TILEPRO_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES),
+
+  /* Number of registers (some are magic, such as network I/O). */
+  TILEPRO_NUM_REGISTERS = 64,
+
+  /* Number of static network registers. */
+  TILEPRO_NUM_SN_REGISTERS = 4
+};
+
+/* Make a few "tile_" variables to simplify common code between
+   architectures.  */
+
+typedef tilepro_bundle_bits tile_bundle_bits;
+#define TILE_BUNDLE_SIZE_IN_BYTES TILEPRO_BUNDLE_SIZE_IN_BYTES
+#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEPRO_BUNDLE_ALIGNMENT_IN_BYTES
+#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
+  TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
+
+/* 64-bit pattern for a { bpt ; nop } bundle. */
+#define TILEPRO_BPT_BUNDLE 0x400b3cae70166000ULL
+
+static __inline unsigned int
+get_BrOff_SN(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_BrOff_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x00007fff) |
+         (((unsigned int)(n >> 20)) & 0x00018000);
+}
+
+static __inline unsigned int
+get_BrType_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0xf);
+}
+
+static __inline unsigned int
+get_Dest_Imm8_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x0000003f) |
+         (((unsigned int)(n >> 43)) & 0x000000c0);
+}
+
+static __inline unsigned int
+get_Dest_SN(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 2)) & 0x3);
+}
+
+static __inline unsigned int
+get_Dest_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Imm16_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm16_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm8_SN(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_ImmOpcodeExtension_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 20)) & 0x7f);
+}
+
+static __inline unsigned int
+get_ImmOpcodeExtension_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 51)) & 0x7f);
+}
+
+static __inline unsigned int
+get_ImmRROpcodeExtension_SN(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 8)) & 0x3);
+}
+
+static __inline unsigned int
+get_JOffLong_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x00007fff) |
+         (((unsigned int)(n >> 20)) & 0x00018000) |
+         (((unsigned int)(n >> 14)) & 0x001e0000) |
+         (((unsigned int)(n >> 16)) & 0x07e00000) |
+         (((unsigned int)(n >> 31)) & 0x18000000);
+}
+
+static __inline unsigned int
+get_JOff_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x00007fff) |
+         (((unsigned int)(n >> 20)) & 0x00018000) |
+         (((unsigned int)(n >> 14)) & 0x001e0000) |
+         (((unsigned int)(n >> 16)) & 0x07e00000) |
+         (((unsigned int)(n >> 31)) & 0x08000000);
+}
+
+static __inline unsigned int
+get_MF_Imm15_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 37)) & 0x00003fff) |
+         (((unsigned int)(n >> 44)) & 0x00004000);
+}
+
+static __inline unsigned int
+get_MMEnd_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MMEnd_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 49)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MMStart_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 23)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MMStart_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 54)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MT_Imm15_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x0000003f) |
+         (((unsigned int)(n >> 37)) & 0x00003fc0) |
+         (((unsigned int)(n >> 44)) & 0x00004000);
+}
+
+static __inline unsigned int
+get_Mode(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 63)) & 0x1);
+}
+
+static __inline unsigned int
+get_NoRegOpcodeExtension_SN(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_SN(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 10)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Opcode_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 28)) & 0x7);
+}
+
+static __inline unsigned int
+get_Opcode_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 59)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 27)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 59)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y2(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 56)) & 0x7);
+}
+
+static __inline unsigned int
+get_RROpcodeExtension_SN(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 4)) & 0xf);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x1ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 49)) & 0x1ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x3);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 49)) & 0x3);
+}
+
+static __inline unsigned int
+get_RouteOpcodeExtension_SN(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_S_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 27)) & 0x1);
+}
+
+static __inline unsigned int
+get_S_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 58)) & 0x1);
+}
+
+static __inline unsigned int
+get_ShAmt_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_ShAmt_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_SrcA_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y2(tilepro_bundle_bits n)
+{
+  return (((n >> 26)) & 0x00000001) |
+         (((unsigned int)(n >> 50)) & 0x0000003e);
+}
+
+static __inline unsigned int
+get_SrcBDest_Y2(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 20)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Src_SN(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 0)) & 0x3);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_Y0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_Y1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_X0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 17)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_X1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 48)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_Y0(tilepro_bundle_bits num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 17)) & 0x7);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_Y1(tilepro_bundle_bits n)
+{
+  return (((unsigned int)(n >> 48)) & 0x7);
+}
+
+
+static __inline int
+sign_extend(int n, int num_bits)
+{
+  int shift = (int)(sizeof(int) * 8 - num_bits);
+  return (n << shift) >> shift;
+}
+
+
+
+static __inline tilepro_bundle_bits
+create_BrOff_SN(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3ff) << 0);
+}
+
+static __inline tilepro_bundle_bits
+create_BrOff_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x00007fff)) << 43) |
+         (((tilepro_bundle_bits)(n & 0x00018000)) << 20);
+}
+
+static __inline tilepro_bundle_bits
+create_BrType_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0xf)) << 31);
+}
+
+static __inline tilepro_bundle_bits
+create_Dest_Imm8_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x0000003f)) << 31) |
+         (((tilepro_bundle_bits)(n & 0x000000c0)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_Dest_SN(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3) << 2);
+}
+
+static __inline tilepro_bundle_bits
+create_Dest_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 0);
+}
+
+static __inline tilepro_bundle_bits
+create_Dest_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tilepro_bundle_bits
+create_Dest_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 0);
+}
+
+static __inline tilepro_bundle_bits
+create_Dest_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tilepro_bundle_bits
+create_Imm16_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xffff) << 12);
+}
+
+static __inline tilepro_bundle_bits
+create_Imm16_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0xffff)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_Imm8_SN(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xff) << 0);
+}
+
+static __inline tilepro_bundle_bits
+create_Imm8_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xff) << 12);
+}
+
+static __inline tilepro_bundle_bits
+create_Imm8_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_Imm8_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xff) << 12);
+}
+
+static __inline tilepro_bundle_bits
+create_Imm8_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_ImmOpcodeExtension_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x7f) << 20);
+}
+
+static __inline tilepro_bundle_bits
+create_ImmOpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x7f)) << 51);
+}
+
+static __inline tilepro_bundle_bits
+create_ImmRROpcodeExtension_SN(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3) << 8);
+}
+
+static __inline tilepro_bundle_bits
+create_JOffLong_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x00007fff)) << 43) |
+         (((tilepro_bundle_bits)(n & 0x00018000)) << 20) |
+         (((tilepro_bundle_bits)(n & 0x001e0000)) << 14) |
+         (((tilepro_bundle_bits)(n & 0x07e00000)) << 16) |
+         (((tilepro_bundle_bits)(n & 0x18000000)) << 31);
+}
+
+static __inline tilepro_bundle_bits
+create_JOff_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x00007fff)) << 43) |
+         (((tilepro_bundle_bits)(n & 0x00018000)) << 20) |
+         (((tilepro_bundle_bits)(n & 0x001e0000)) << 14) |
+         (((tilepro_bundle_bits)(n & 0x07e00000)) << 16) |
+         (((tilepro_bundle_bits)(n & 0x08000000)) << 31);
+}
+
+static __inline tilepro_bundle_bits
+create_MF_Imm15_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x00003fff)) << 37) |
+         (((tilepro_bundle_bits)(n & 0x00004000)) << 44);
+}
+
+static __inline tilepro_bundle_bits
+create_MMEnd_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x1f) << 18);
+}
+
+static __inline tilepro_bundle_bits
+create_MMEnd_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x1f)) << 49);
+}
+
+static __inline tilepro_bundle_bits
+create_MMStart_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x1f) << 23);
+}
+
+static __inline tilepro_bundle_bits
+create_MMStart_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x1f)) << 54);
+}
+
+static __inline tilepro_bundle_bits
+create_MT_Imm15_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x0000003f)) << 31) |
+         (((tilepro_bundle_bits)(n & 0x00003fc0)) << 37) |
+         (((tilepro_bundle_bits)(n & 0x00004000)) << 44);
+}
+
+static __inline tilepro_bundle_bits
+create_Mode(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x1)) << 63);
+}
+
+static __inline tilepro_bundle_bits
+create_NoRegOpcodeExtension_SN(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xf) << 0);
+}
+
+static __inline tilepro_bundle_bits
+create_Opcode_SN(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 10);
+}
+
+static __inline tilepro_bundle_bits
+create_Opcode_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x7) << 28);
+}
+
+static __inline tilepro_bundle_bits
+create_Opcode_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0xf)) << 59);
+}
+
+static __inline tilepro_bundle_bits
+create_Opcode_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xf) << 27);
+}
+
+static __inline tilepro_bundle_bits
+create_Opcode_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0xf)) << 59);
+}
+
+static __inline tilepro_bundle_bits
+create_Opcode_Y2(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x7)) << 56);
+}
+
+static __inline tilepro_bundle_bits
+create_RROpcodeExtension_SN(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0xf) << 4);
+}
+
+static __inline tilepro_bundle_bits
+create_RRROpcodeExtension_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x1ff) << 18);
+}
+
+static __inline tilepro_bundle_bits
+create_RRROpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x1ff)) << 49);
+}
+
+static __inline tilepro_bundle_bits
+create_RRROpcodeExtension_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3) << 18);
+}
+
+static __inline tilepro_bundle_bits
+create_RRROpcodeExtension_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x3)) << 49);
+}
+
+static __inline tilepro_bundle_bits
+create_RouteOpcodeExtension_SN(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3ff) << 0);
+}
+
+static __inline tilepro_bundle_bits
+create_S_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x1) << 27);
+}
+
+static __inline tilepro_bundle_bits
+create_S_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x1)) << 58);
+}
+
+static __inline tilepro_bundle_bits
+create_ShAmt_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x1f) << 12);
+}
+
+static __inline tilepro_bundle_bits
+create_ShAmt_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_ShAmt_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x1f) << 12);
+}
+
+static __inline tilepro_bundle_bits
+create_ShAmt_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcA_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 6);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcA_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcA_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 6);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcA_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcA_Y2(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x00000001) << 26) |
+         (((tilepro_bundle_bits)(n & 0x0000003e)) << 50);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcBDest_Y2(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 20);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcB_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 12);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcB_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcB_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3f) << 12);
+}
+
+static __inline tilepro_bundle_bits
+create_SrcB_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_Src_SN(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3) << 0);
+}
+
+static __inline tilepro_bundle_bits
+create_UnOpcodeExtension_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x1f) << 12);
+}
+
+static __inline tilepro_bundle_bits
+create_UnOpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_UnOpcodeExtension_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x1f) << 12);
+}
+
+static __inline tilepro_bundle_bits
+create_UnOpcodeExtension_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tilepro_bundle_bits
+create_UnShOpcodeExtension_X0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x3ff) << 17);
+}
+
+static __inline tilepro_bundle_bits
+create_UnShOpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x3ff)) << 48);
+}
+
+static __inline tilepro_bundle_bits
+create_UnShOpcodeExtension_Y0(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return ((n & 0x7) << 17);
+}
+
+static __inline tilepro_bundle_bits
+create_UnShOpcodeExtension_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilepro_bundle_bits)(n & 0x7)) << 48);
+}
+
+
+enum
+{
+  ADDBS_U_SPECIAL_0_OPCODE_X0 = 98,
+  ADDBS_U_SPECIAL_0_OPCODE_X1 = 68,
+  ADDB_SPECIAL_0_OPCODE_X0 = 1,
+  ADDB_SPECIAL_0_OPCODE_X1 = 1,
+  ADDHS_SPECIAL_0_OPCODE_X0 = 99,
+  ADDHS_SPECIAL_0_OPCODE_X1 = 69,
+  ADDH_SPECIAL_0_OPCODE_X0 = 2,
+  ADDH_SPECIAL_0_OPCODE_X1 = 2,
+  ADDIB_IMM_0_OPCODE_X0 = 1,
+  ADDIB_IMM_0_OPCODE_X1 = 1,
+  ADDIH_IMM_0_OPCODE_X0 = 2,
+  ADDIH_IMM_0_OPCODE_X1 = 2,
+  ADDI_IMM_0_OPCODE_X0 = 3,
+  ADDI_IMM_0_OPCODE_X1 = 3,
+  ADDI_IMM_1_OPCODE_SN = 1,
+  ADDI_OPCODE_Y0 = 9,
+  ADDI_OPCODE_Y1 = 7,
+  ADDLIS_OPCODE_X0 = 1,
+  ADDLIS_OPCODE_X1 = 2,
+  ADDLI_OPCODE_X0 = 2,
+  ADDLI_OPCODE_X1 = 3,
+  ADDS_SPECIAL_0_OPCODE_X0 = 96,
+  ADDS_SPECIAL_0_OPCODE_X1 = 66,
+  ADD_SPECIAL_0_OPCODE_X0 = 3,
+  ADD_SPECIAL_0_OPCODE_X1 = 3,
+  ADD_SPECIAL_0_OPCODE_Y0 = 0,
+  ADD_SPECIAL_0_OPCODE_Y1 = 0,
+  ADIFFB_U_SPECIAL_0_OPCODE_X0 = 4,
+  ADIFFH_SPECIAL_0_OPCODE_X0 = 5,
+  ANDI_IMM_0_OPCODE_X0 = 1,
+  ANDI_IMM_0_OPCODE_X1 = 4,
+  ANDI_OPCODE_Y0 = 10,
+  ANDI_OPCODE_Y1 = 8,
+  AND_SPECIAL_0_OPCODE_X0 = 6,
+  AND_SPECIAL_0_OPCODE_X1 = 4,
+  AND_SPECIAL_2_OPCODE_Y0 = 0,
+  AND_SPECIAL_2_OPCODE_Y1 = 0,
+  AULI_OPCODE_X0 = 3,
+  AULI_OPCODE_X1 = 4,
+  AVGB_U_SPECIAL_0_OPCODE_X0 = 7,
+  AVGH_SPECIAL_0_OPCODE_X0 = 8,
+  BBNST_BRANCH_OPCODE_X1 = 15,
+  BBNS_BRANCH_OPCODE_X1 = 14,
+  BBNS_OPCODE_SN = 63,
+  BBST_BRANCH_OPCODE_X1 = 13,
+  BBS_BRANCH_OPCODE_X1 = 12,
+  BBS_OPCODE_SN = 62,
+  BGEZT_BRANCH_OPCODE_X1 = 7,
+  BGEZ_BRANCH_OPCODE_X1 = 6,
+  BGEZ_OPCODE_SN = 61,
+  BGZT_BRANCH_OPCODE_X1 = 5,
+  BGZ_BRANCH_OPCODE_X1 = 4,
+  BGZ_OPCODE_SN = 58,
+  BITX_UN_0_SHUN_0_OPCODE_X0 = 1,
+  BITX_UN_0_SHUN_0_OPCODE_Y0 = 1,
+  BLEZT_BRANCH_OPCODE_X1 = 11,
+  BLEZ_BRANCH_OPCODE_X1 = 10,
+  BLEZ_OPCODE_SN = 59,
+  BLZT_BRANCH_OPCODE_X1 = 9,
+  BLZ_BRANCH_OPCODE_X1 = 8,
+  BLZ_OPCODE_SN = 60,
+  BNZT_BRANCH_OPCODE_X1 = 3,
+  BNZ_BRANCH_OPCODE_X1 = 2,
+  BNZ_OPCODE_SN = 57,
+  BPT_NOREG_RR_IMM_0_OPCODE_SN = 1,
+  BRANCH_OPCODE_X1 = 5,
+  BYTEX_UN_0_SHUN_0_OPCODE_X0 = 2,
+  BYTEX_UN_0_SHUN_0_OPCODE_Y0 = 2,
+  BZT_BRANCH_OPCODE_X1 = 1,
+  BZ_BRANCH_OPCODE_X1 = 0,
+  BZ_OPCODE_SN = 56,
+  CLZ_UN_0_SHUN_0_OPCODE_X0 = 3,
+  CLZ_UN_0_SHUN_0_OPCODE_Y0 = 3,
+  CRC32_32_SPECIAL_0_OPCODE_X0 = 9,
+  CRC32_8_SPECIAL_0_OPCODE_X0 = 10,
+  CTZ_UN_0_SHUN_0_OPCODE_X0 = 4,
+  CTZ_UN_0_SHUN_0_OPCODE_Y0 = 4,
+  DRAIN_UN_0_SHUN_0_OPCODE_X1 = 1,
+  DTLBPR_UN_0_SHUN_0_OPCODE_X1 = 2,
+  DWORD_ALIGN_SPECIAL_0_OPCODE_X0 = 95,
+  FINV_UN_0_SHUN_0_OPCODE_X1 = 3,
+  FLUSH_UN_0_SHUN_0_OPCODE_X1 = 4,
+  FNOP_NOREG_RR_IMM_0_OPCODE_SN = 3,
+  FNOP_UN_0_SHUN_0_OPCODE_X0 = 5,
+  FNOP_UN_0_SHUN_0_OPCODE_X1 = 5,
+  FNOP_UN_0_SHUN_0_OPCODE_Y0 = 5,
+  FNOP_UN_0_SHUN_0_OPCODE_Y1 = 1,
+  HALT_NOREG_RR_IMM_0_OPCODE_SN = 0,
+  ICOH_UN_0_SHUN_0_OPCODE_X1 = 6,
+  ILL_UN_0_SHUN_0_OPCODE_X1 = 7,
+  ILL_UN_0_SHUN_0_OPCODE_Y1 = 2,
+  IMM_0_OPCODE_SN = 0,
+  IMM_0_OPCODE_X0 = 4,
+  IMM_0_OPCODE_X1 = 6,
+  IMM_1_OPCODE_SN = 1,
+  IMM_OPCODE_0_X0 = 5,
+  INTHB_SPECIAL_0_OPCODE_X0 = 11,
+  INTHB_SPECIAL_0_OPCODE_X1 = 5,
+  INTHH_SPECIAL_0_OPCODE_X0 = 12,
+  INTHH_SPECIAL_0_OPCODE_X1 = 6,
+  INTLB_SPECIAL_0_OPCODE_X0 = 13,
+  INTLB_SPECIAL_0_OPCODE_X1 = 7,
+  INTLH_SPECIAL_0_OPCODE_X0 = 14,
+  INTLH_SPECIAL_0_OPCODE_X1 = 8,
+  INV_UN_0_SHUN_0_OPCODE_X1 = 8,
+  IRET_UN_0_SHUN_0_OPCODE_X1 = 9,
+  JALB_OPCODE_X1 = 13,
+  JALF_OPCODE_X1 = 12,
+  JALRP_SPECIAL_0_OPCODE_X1 = 9,
+  JALRR_IMM_1_OPCODE_SN = 3,
+  JALR_RR_IMM_0_OPCODE_SN = 5,
+  JALR_SPECIAL_0_OPCODE_X1 = 10,
+  JB_OPCODE_X1 = 11,
+  JF_OPCODE_X1 = 10,
+  JRP_SPECIAL_0_OPCODE_X1 = 11,
+  JRR_IMM_1_OPCODE_SN = 2,
+  JR_RR_IMM_0_OPCODE_SN = 4,
+  JR_SPECIAL_0_OPCODE_X1 = 12,
+  LBADD_IMM_0_OPCODE_X1 = 22,
+  LBADD_U_IMM_0_OPCODE_X1 = 23,
+  LB_OPCODE_Y2 = 0,
+  LB_UN_0_SHUN_0_OPCODE_X1 = 10,
+  LB_U_OPCODE_Y2 = 1,
+  LB_U_UN_0_SHUN_0_OPCODE_X1 = 11,
+  LHADD_IMM_0_OPCODE_X1 = 24,
+  LHADD_U_IMM_0_OPCODE_X1 = 25,
+  LH_OPCODE_Y2 = 2,
+  LH_UN_0_SHUN_0_OPCODE_X1 = 12,
+  LH_U_OPCODE_Y2 = 3,
+  LH_U_UN_0_SHUN_0_OPCODE_X1 = 13,
+  LNK_SPECIAL_0_OPCODE_X1 = 13,
+  LWADD_IMM_0_OPCODE_X1 = 26,
+  LWADD_NA_IMM_0_OPCODE_X1 = 27,
+  LW_NA_UN_0_SHUN_0_OPCODE_X1 = 24,
+  LW_OPCODE_Y2 = 4,
+  LW_UN_0_SHUN_0_OPCODE_X1 = 14,
+  MAXB_U_SPECIAL_0_OPCODE_X0 = 15,
+  MAXB_U_SPECIAL_0_OPCODE_X1 = 14,
+  MAXH_SPECIAL_0_OPCODE_X0 = 16,
+  MAXH_SPECIAL_0_OPCODE_X1 = 15,
+  MAXIB_U_IMM_0_OPCODE_X0 = 4,
+  MAXIB_U_IMM_0_OPCODE_X1 = 5,
+  MAXIH_IMM_0_OPCODE_X0 = 5,
+  MAXIH_IMM_0_OPCODE_X1 = 6,
+  MFSPR_IMM_0_OPCODE_X1 = 7,
+  MF_UN_0_SHUN_0_OPCODE_X1 = 15,
+  MINB_U_SPECIAL_0_OPCODE_X0 = 17,
+  MINB_U_SPECIAL_0_OPCODE_X1 = 16,
+  MINH_SPECIAL_0_OPCODE_X0 = 18,
+  MINH_SPECIAL_0_OPCODE_X1 = 17,
+  MINIB_U_IMM_0_OPCODE_X0 = 6,
+  MINIB_U_IMM_0_OPCODE_X1 = 8,
+  MINIH_IMM_0_OPCODE_X0 = 7,
+  MINIH_IMM_0_OPCODE_X1 = 9,
+  MM_OPCODE_X0 = 6,
+  MM_OPCODE_X1 = 7,
+  MNZB_SPECIAL_0_OPCODE_X0 = 19,
+  MNZB_SPECIAL_0_OPCODE_X1 = 18,
+  MNZH_SPECIAL_0_OPCODE_X0 = 20,
+  MNZH_SPECIAL_0_OPCODE_X1 = 19,
+  MNZ_SPECIAL_0_OPCODE_X0 = 21,
+  MNZ_SPECIAL_0_OPCODE_X1 = 20,
+  MNZ_SPECIAL_1_OPCODE_Y0 = 0,
+  MNZ_SPECIAL_1_OPCODE_Y1 = 1,
+  MOVEI_IMM_1_OPCODE_SN = 0,
+  MOVE_RR_IMM_0_OPCODE_SN = 8,
+  MTSPR_IMM_0_OPCODE_X1 = 10,
+  MULHHA_SS_SPECIAL_0_OPCODE_X0 = 22,
+  MULHHA_SS_SPECIAL_7_OPCODE_Y0 = 0,
+  MULHHA_SU_SPECIAL_0_OPCODE_X0 = 23,
+  MULHHA_UU_SPECIAL_0_OPCODE_X0 = 24,
+  MULHHA_UU_SPECIAL_7_OPCODE_Y0 = 1,
+  MULHHSA_UU_SPECIAL_0_OPCODE_X0 = 25,
+  MULHH_SS_SPECIAL_0_OPCODE_X0 = 26,
+  MULHH_SS_SPECIAL_6_OPCODE_Y0 = 0,
+  MULHH_SU_SPECIAL_0_OPCODE_X0 = 27,
+  MULHH_UU_SPECIAL_0_OPCODE_X0 = 28,
+  MULHH_UU_SPECIAL_6_OPCODE_Y0 = 1,
+  MULHLA_SS_SPECIAL_0_OPCODE_X0 = 29,
+  MULHLA_SU_SPECIAL_0_OPCODE_X0 = 30,
+  MULHLA_US_SPECIAL_0_OPCODE_X0 = 31,
+  MULHLA_UU_SPECIAL_0_OPCODE_X0 = 32,
+  MULHLSA_UU_SPECIAL_0_OPCODE_X0 = 33,
+  MULHLSA_UU_SPECIAL_5_OPCODE_Y0 = 0,
+  MULHL_SS_SPECIAL_0_OPCODE_X0 = 34,
+  MULHL_SU_SPECIAL_0_OPCODE_X0 = 35,
+  MULHL_US_SPECIAL_0_OPCODE_X0 = 36,
+  MULHL_UU_SPECIAL_0_OPCODE_X0 = 37,
+  MULLLA_SS_SPECIAL_0_OPCODE_X0 = 38,
+  MULLLA_SS_SPECIAL_7_OPCODE_Y0 = 2,
+  MULLLA_SU_SPECIAL_0_OPCODE_X0 = 39,
+  MULLLA_UU_SPECIAL_0_OPCODE_X0 = 40,
+  MULLLA_UU_SPECIAL_7_OPCODE_Y0 = 3,
+  MULLLSA_UU_SPECIAL_0_OPCODE_X0 = 41,
+  MULLL_SS_SPECIAL_0_OPCODE_X0 = 42,
+  MULLL_SS_SPECIAL_6_OPCODE_Y0 = 2,
+  MULLL_SU_SPECIAL_0_OPCODE_X0 = 43,
+  MULLL_UU_SPECIAL_0_OPCODE_X0 = 44,
+  MULLL_UU_SPECIAL_6_OPCODE_Y0 = 3,
+  MVNZ_SPECIAL_0_OPCODE_X0 = 45,
+  MVNZ_SPECIAL_1_OPCODE_Y0 = 1,
+  MVZ_SPECIAL_0_OPCODE_X0 = 46,
+  MVZ_SPECIAL_1_OPCODE_Y0 = 2,
+  MZB_SPECIAL_0_OPCODE_X0 = 47,
+  MZB_SPECIAL_0_OPCODE_X1 = 21,
+  MZH_SPECIAL_0_OPCODE_X0 = 48,
+  MZH_SPECIAL_0_OPCODE_X1 = 22,
+  MZ_SPECIAL_0_OPCODE_X0 = 49,
+  MZ_SPECIAL_0_OPCODE_X1 = 23,
+  MZ_SPECIAL_1_OPCODE_Y0 = 3,
+  MZ_SPECIAL_1_OPCODE_Y1 = 2,
+  NAP_UN_0_SHUN_0_OPCODE_X1 = 16,
+  NOP_NOREG_RR_IMM_0_OPCODE_SN = 2,
+  NOP_UN_0_SHUN_0_OPCODE_X0 = 6,
+  NOP_UN_0_SHUN_0_OPCODE_X1 = 17,
+  NOP_UN_0_SHUN_0_OPCODE_Y0 = 6,
+  NOP_UN_0_SHUN_0_OPCODE_Y1 = 3,
+  NOREG_RR_IMM_0_OPCODE_SN = 0,
+  NOR_SPECIAL_0_OPCODE_X0 = 50,
+  NOR_SPECIAL_0_OPCODE_X1 = 24,
+  NOR_SPECIAL_2_OPCODE_Y0 = 1,
+  NOR_SPECIAL_2_OPCODE_Y1 = 1,
+  ORI_IMM_0_OPCODE_X0 = 8,
+  ORI_IMM_0_OPCODE_X1 = 11,
+  ORI_OPCODE_Y0 = 11,
+  ORI_OPCODE_Y1 = 9,
+  OR_SPECIAL_0_OPCODE_X0 = 51,
+  OR_SPECIAL_0_OPCODE_X1 = 25,
+  OR_SPECIAL_2_OPCODE_Y0 = 2,
+  OR_SPECIAL_2_OPCODE_Y1 = 2,
+  PACKBS_U_SPECIAL_0_OPCODE_X0 = 103,
+  PACKBS_U_SPECIAL_0_OPCODE_X1 = 73,
+  PACKHB_SPECIAL_0_OPCODE_X0 = 52,
+  PACKHB_SPECIAL_0_OPCODE_X1 = 26,
+  PACKHS_SPECIAL_0_OPCODE_X0 = 102,
+  PACKHS_SPECIAL_0_OPCODE_X1 = 72,
+  PACKLB_SPECIAL_0_OPCODE_X0 = 53,
+  PACKLB_SPECIAL_0_OPCODE_X1 = 27,
+  PCNT_UN_0_SHUN_0_OPCODE_X0 = 7,
+  PCNT_UN_0_SHUN_0_OPCODE_Y0 = 7,
+  RLI_SHUN_0_OPCODE_X0 = 1,
+  RLI_SHUN_0_OPCODE_X1 = 1,
+  RLI_SHUN_0_OPCODE_Y0 = 1,
+  RLI_SHUN_0_OPCODE_Y1 = 1,
+  RL_SPECIAL_0_OPCODE_X0 = 54,
+  RL_SPECIAL_0_OPCODE_X1 = 28,
+  RL_SPECIAL_3_OPCODE_Y0 = 0,
+  RL_SPECIAL_3_OPCODE_Y1 = 0,
+  RR_IMM_0_OPCODE_SN = 0,
+  S1A_SPECIAL_0_OPCODE_X0 = 55,
+  S1A_SPECIAL_0_OPCODE_X1 = 29,
+  S1A_SPECIAL_0_OPCODE_Y0 = 1,
+  S1A_SPECIAL_0_OPCODE_Y1 = 1,
+  S2A_SPECIAL_0_OPCODE_X0 = 56,
+  S2A_SPECIAL_0_OPCODE_X1 = 30,
+  S2A_SPECIAL_0_OPCODE_Y0 = 2,
+  S2A_SPECIAL_0_OPCODE_Y1 = 2,
+  S3A_SPECIAL_0_OPCODE_X0 = 57,
+  S3A_SPECIAL_0_OPCODE_X1 = 31,
+  S3A_SPECIAL_5_OPCODE_Y0 = 1,
+  S3A_SPECIAL_5_OPCODE_Y1 = 1,
+  SADAB_U_SPECIAL_0_OPCODE_X0 = 58,
+  SADAH_SPECIAL_0_OPCODE_X0 = 59,
+  SADAH_U_SPECIAL_0_OPCODE_X0 = 60,
+  SADB_U_SPECIAL_0_OPCODE_X0 = 61,
+  SADH_SPECIAL_0_OPCODE_X0 = 62,
+  SADH_U_SPECIAL_0_OPCODE_X0 = 63,
+  SBADD_IMM_0_OPCODE_X1 = 28,
+  SB_OPCODE_Y2 = 5,
+  SB_SPECIAL_0_OPCODE_X1 = 32,
+  SEQB_SPECIAL_0_OPCODE_X0 = 64,
+  SEQB_SPECIAL_0_OPCODE_X1 = 33,
+  SEQH_SPECIAL_0_OPCODE_X0 = 65,
+  SEQH_SPECIAL_0_OPCODE_X1 = 34,
+  SEQIB_IMM_0_OPCODE_X0 = 9,
+  SEQIB_IMM_0_OPCODE_X1 = 12,
+  SEQIH_IMM_0_OPCODE_X0 = 10,
+  SEQIH_IMM_0_OPCODE_X1 = 13,
+  SEQI_IMM_0_OPCODE_X0 = 11,
+  SEQI_IMM_0_OPCODE_X1 = 14,
+  SEQI_OPCODE_Y0 = 12,
+  SEQI_OPCODE_Y1 = 10,
+  SEQ_SPECIAL_0_OPCODE_X0 = 66,
+  SEQ_SPECIAL_0_OPCODE_X1 = 35,
+  SEQ_SPECIAL_5_OPCODE_Y0 = 2,
+  SEQ_SPECIAL_5_OPCODE_Y1 = 2,
+  SHADD_IMM_0_OPCODE_X1 = 29,
+  SHL8II_IMM_0_OPCODE_SN = 3,
+  SHLB_SPECIAL_0_OPCODE_X0 = 67,
+  SHLB_SPECIAL_0_OPCODE_X1 = 36,
+  SHLH_SPECIAL_0_OPCODE_X0 = 68,
+  SHLH_SPECIAL_0_OPCODE_X1 = 37,
+  SHLIB_SHUN_0_OPCODE_X0 = 2,
+  SHLIB_SHUN_0_OPCODE_X1 = 2,
+  SHLIH_SHUN_0_OPCODE_X0 = 3,
+  SHLIH_SHUN_0_OPCODE_X1 = 3,
+  SHLI_SHUN_0_OPCODE_X0 = 4,
+  SHLI_SHUN_0_OPCODE_X1 = 4,
+  SHLI_SHUN_0_OPCODE_Y0 = 2,
+  SHLI_SHUN_0_OPCODE_Y1 = 2,
+  SHL_SPECIAL_0_OPCODE_X0 = 69,
+  SHL_SPECIAL_0_OPCODE_X1 = 38,
+  SHL_SPECIAL_3_OPCODE_Y0 = 1,
+  SHL_SPECIAL_3_OPCODE_Y1 = 1,
+  SHR1_RR_IMM_0_OPCODE_SN = 9,
+  SHRB_SPECIAL_0_OPCODE_X0 = 70,
+  SHRB_SPECIAL_0_OPCODE_X1 = 39,
+  SHRH_SPECIAL_0_OPCODE_X0 = 71,
+  SHRH_SPECIAL_0_OPCODE_X1 = 40,
+  SHRIB_SHUN_0_OPCODE_X0 = 5,
+  SHRIB_SHUN_0_OPCODE_X1 = 5,
+  SHRIH_SHUN_0_OPCODE_X0 = 6,
+  SHRIH_SHUN_0_OPCODE_X1 = 6,
+  SHRI_SHUN_0_OPCODE_X0 = 7,
+  SHRI_SHUN_0_OPCODE_X1 = 7,
+  SHRI_SHUN_0_OPCODE_Y0 = 3,
+  SHRI_SHUN_0_OPCODE_Y1 = 3,
+  SHR_SPECIAL_0_OPCODE_X0 = 72,
+  SHR_SPECIAL_0_OPCODE_X1 = 41,
+  SHR_SPECIAL_3_OPCODE_Y0 = 2,
+  SHR_SPECIAL_3_OPCODE_Y1 = 2,
+  SHUN_0_OPCODE_X0 = 7,
+  SHUN_0_OPCODE_X1 = 8,
+  SHUN_0_OPCODE_Y0 = 13,
+  SHUN_0_OPCODE_Y1 = 11,
+  SH_OPCODE_Y2 = 6,
+  SH_SPECIAL_0_OPCODE_X1 = 42,
+  SLTB_SPECIAL_0_OPCODE_X0 = 73,
+  SLTB_SPECIAL_0_OPCODE_X1 = 43,
+  SLTB_U_SPECIAL_0_OPCODE_X0 = 74,
+  SLTB_U_SPECIAL_0_OPCODE_X1 = 44,
+  SLTEB_SPECIAL_0_OPCODE_X0 = 75,
+  SLTEB_SPECIAL_0_OPCODE_X1 = 45,
+  SLTEB_U_SPECIAL_0_OPCODE_X0 = 76,
+  SLTEB_U_SPECIAL_0_OPCODE_X1 = 46,
+  SLTEH_SPECIAL_0_OPCODE_X0 = 77,
+  SLTEH_SPECIAL_0_OPCODE_X1 = 47,
+  SLTEH_U_SPECIAL_0_OPCODE_X0 = 78,
+  SLTEH_U_SPECIAL_0_OPCODE_X1 = 48,
+  SLTE_SPECIAL_0_OPCODE_X0 = 79,
+  SLTE_SPECIAL_0_OPCODE_X1 = 49,
+  SLTE_SPECIAL_4_OPCODE_Y0 = 0,
+  SLTE_SPECIAL_4_OPCODE_Y1 = 0,
+  SLTE_U_SPECIAL_0_OPCODE_X0 = 80,
+  SLTE_U_SPECIAL_0_OPCODE_X1 = 50,
+  SLTE_U_SPECIAL_4_OPCODE_Y0 = 1,
+  SLTE_U_SPECIAL_4_OPCODE_Y1 = 1,
+  SLTH_SPECIAL_0_OPCODE_X0 = 81,
+  SLTH_SPECIAL_0_OPCODE_X1 = 51,
+  SLTH_U_SPECIAL_0_OPCODE_X0 = 82,
+  SLTH_U_SPECIAL_0_OPCODE_X1 = 52,
+  SLTIB_IMM_0_OPCODE_X0 = 12,
+  SLTIB_IMM_0_OPCODE_X1 = 15,
+  SLTIB_U_IMM_0_OPCODE_X0 = 13,
+  SLTIB_U_IMM_0_OPCODE_X1 = 16,
+  SLTIH_IMM_0_OPCODE_X0 = 14,
+  SLTIH_IMM_0_OPCODE_X1 = 17,
+  SLTIH_U_IMM_0_OPCODE_X0 = 15,
+  SLTIH_U_IMM_0_OPCODE_X1 = 18,
+  SLTI_IMM_0_OPCODE_X0 = 16,
+  SLTI_IMM_0_OPCODE_X1 = 19,
+  SLTI_OPCODE_Y0 = 14,
+  SLTI_OPCODE_Y1 = 12,
+  SLTI_U_IMM_0_OPCODE_X0 = 17,
+  SLTI_U_IMM_0_OPCODE_X1 = 20,
+  SLTI_U_OPCODE_Y0 = 15,
+  SLTI_U_OPCODE_Y1 = 13,
+  SLT_SPECIAL_0_OPCODE_X0 = 83,
+  SLT_SPECIAL_0_OPCODE_X1 = 53,
+  SLT_SPECIAL_4_OPCODE_Y0 = 2,
+  SLT_SPECIAL_4_OPCODE_Y1 = 2,
+  SLT_U_SPECIAL_0_OPCODE_X0 = 84,
+  SLT_U_SPECIAL_0_OPCODE_X1 = 54,
+  SLT_U_SPECIAL_4_OPCODE_Y0 = 3,
+  SLT_U_SPECIAL_4_OPCODE_Y1 = 3,
+  SNEB_SPECIAL_0_OPCODE_X0 = 85,
+  SNEB_SPECIAL_0_OPCODE_X1 = 55,
+  SNEH_SPECIAL_0_OPCODE_X0 = 86,
+  SNEH_SPECIAL_0_OPCODE_X1 = 56,
+  SNE_SPECIAL_0_OPCODE_X0 = 87,
+  SNE_SPECIAL_0_OPCODE_X1 = 57,
+  SNE_SPECIAL_5_OPCODE_Y0 = 3,
+  SNE_SPECIAL_5_OPCODE_Y1 = 3,
+  SPECIAL_0_OPCODE_X0 = 0,
+  SPECIAL_0_OPCODE_X1 = 1,
+  SPECIAL_0_OPCODE_Y0 = 1,
+  SPECIAL_0_OPCODE_Y1 = 1,
+  SPECIAL_1_OPCODE_Y0 = 2,
+  SPECIAL_1_OPCODE_Y1 = 2,
+  SPECIAL_2_OPCODE_Y0 = 3,
+  SPECIAL_2_OPCODE_Y1 = 3,
+  SPECIAL_3_OPCODE_Y0 = 4,
+  SPECIAL_3_OPCODE_Y1 = 4,
+  SPECIAL_4_OPCODE_Y0 = 5,
+  SPECIAL_4_OPCODE_Y1 = 5,
+  SPECIAL_5_OPCODE_Y0 = 6,
+  SPECIAL_5_OPCODE_Y1 = 6,
+  SPECIAL_6_OPCODE_Y0 = 7,
+  SPECIAL_7_OPCODE_Y0 = 8,
+  SRAB_SPECIAL_0_OPCODE_X0 = 88,
+  SRAB_SPECIAL_0_OPCODE_X1 = 58,
+  SRAH_SPECIAL_0_OPCODE_X0 = 89,
+  SRAH_SPECIAL_0_OPCODE_X1 = 59,
+  SRAIB_SHUN_0_OPCODE_X0 = 8,
+  SRAIB_SHUN_0_OPCODE_X1 = 8,
+  SRAIH_SHUN_0_OPCODE_X0 = 9,
+  SRAIH_SHUN_0_OPCODE_X1 = 9,
+  SRAI_SHUN_0_OPCODE_X0 = 10,
+  SRAI_SHUN_0_OPCODE_X1 = 10,
+  SRAI_SHUN_0_OPCODE_Y0 = 4,
+  SRAI_SHUN_0_OPCODE_Y1 = 4,
+  SRA_SPECIAL_0_OPCODE_X0 = 90,
+  SRA_SPECIAL_0_OPCODE_X1 = 60,
+  SRA_SPECIAL_3_OPCODE_Y0 = 3,
+  SRA_SPECIAL_3_OPCODE_Y1 = 3,
+  SUBBS_U_SPECIAL_0_OPCODE_X0 = 100,
+  SUBBS_U_SPECIAL_0_OPCODE_X1 = 70,
+  SUBB_SPECIAL_0_OPCODE_X0 = 91,
+  SUBB_SPECIAL_0_OPCODE_X1 = 61,
+  SUBHS_SPECIAL_0_OPCODE_X0 = 101,
+  SUBHS_SPECIAL_0_OPCODE_X1 = 71,
+  SUBH_SPECIAL_0_OPCODE_X0 = 92,
+  SUBH_SPECIAL_0_OPCODE_X1 = 62,
+  SUBS_SPECIAL_0_OPCODE_X0 = 97,
+  SUBS_SPECIAL_0_OPCODE_X1 = 67,
+  SUB_SPECIAL_0_OPCODE_X0 = 93,
+  SUB_SPECIAL_0_OPCODE_X1 = 63,
+  SUB_SPECIAL_0_OPCODE_Y0 = 3,
+  SUB_SPECIAL_0_OPCODE_Y1 = 3,
+  SWADD_IMM_0_OPCODE_X1 = 30,
+  SWINT0_UN_0_SHUN_0_OPCODE_X1 = 18,
+  SWINT1_UN_0_SHUN_0_OPCODE_X1 = 19,
+  SWINT2_UN_0_SHUN_0_OPCODE_X1 = 20,
+  SWINT3_UN_0_SHUN_0_OPCODE_X1 = 21,
+  SW_OPCODE_Y2 = 7,
+  SW_SPECIAL_0_OPCODE_X1 = 64,
+  TBLIDXB0_UN_0_SHUN_0_OPCODE_X0 = 8,
+  TBLIDXB0_UN_0_SHUN_0_OPCODE_Y0 = 8,
+  TBLIDXB1_UN_0_SHUN_0_OPCODE_X0 = 9,
+  TBLIDXB1_UN_0_SHUN_0_OPCODE_Y0 = 9,
+  TBLIDXB2_UN_0_SHUN_0_OPCODE_X0 = 10,
+  TBLIDXB2_UN_0_SHUN_0_OPCODE_Y0 = 10,
+  TBLIDXB3_UN_0_SHUN_0_OPCODE_X0 = 11,
+  TBLIDXB3_UN_0_SHUN_0_OPCODE_Y0 = 11,
+  TNS_UN_0_SHUN_0_OPCODE_X1 = 22,
+  UN_0_SHUN_0_OPCODE_X0 = 11,
+  UN_0_SHUN_0_OPCODE_X1 = 11,
+  UN_0_SHUN_0_OPCODE_Y0 = 5,
+  UN_0_SHUN_0_OPCODE_Y1 = 5,
+  WH64_UN_0_SHUN_0_OPCODE_X1 = 23,
+  XORI_IMM_0_OPCODE_X0 = 2,
+  XORI_IMM_0_OPCODE_X1 = 21,
+  XOR_SPECIAL_0_OPCODE_X0 = 94,
+  XOR_SPECIAL_0_OPCODE_X1 = 65,
+  XOR_SPECIAL_2_OPCODE_Y0 = 3,
+  XOR_SPECIAL_2_OPCODE_Y1 = 3
+};
+
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __ARCH_OPCODE_H__ */
index aec60dc..0bb4264 100644 (file)
@@ -1,5 +1,7 @@
 include include/asm-generic/Kbuild.asm
 
+header-y += ../arch/
+
 header-y += ucontext.h
 header-y += hardwall.h
 
diff --git a/arch/tile/include/asm/opcode-tile_32.h b/arch/tile/include/asm/opcode-tile_32.h
deleted file mode 100644 (file)
index 03df7b1..0000000
+++ /dev/null
@@ -1,1513 +0,0 @@
-/* tile.h -- Header file for TILE opcode table
-   Copyright (C) 2005 Free Software Foundation, Inc.
-   Contributed by Tilera Corp. */
-
-#ifndef opcode_tile_h
-#define opcode_tile_h
-
-typedef unsigned long long tile_bundle_bits;
-
-
-enum
-{
-  TILE_MAX_OPERANDS = 5 /* mm */
-};
-
-typedef enum
-{
-  TILE_OPC_BPT,
-  TILE_OPC_INFO,
-  TILE_OPC_INFOL,
-  TILE_OPC_J,
-  TILE_OPC_JAL,
-  TILE_OPC_MOVE,
-  TILE_OPC_MOVE_SN,
-  TILE_OPC_MOVEI,
-  TILE_OPC_MOVEI_SN,
-  TILE_OPC_MOVELI,
-  TILE_OPC_MOVELI_SN,
-  TILE_OPC_MOVELIS,
-  TILE_OPC_PREFETCH,
-  TILE_OPC_RAISE,
-  TILE_OPC_ADD,
-  TILE_OPC_ADD_SN,
-  TILE_OPC_ADDB,
-  TILE_OPC_ADDB_SN,
-  TILE_OPC_ADDBS_U,
-  TILE_OPC_ADDBS_U_SN,
-  TILE_OPC_ADDH,
-  TILE_OPC_ADDH_SN,
-  TILE_OPC_ADDHS,
-  TILE_OPC_ADDHS_SN,
-  TILE_OPC_ADDI,
-  TILE_OPC_ADDI_SN,
-  TILE_OPC_ADDIB,
-  TILE_OPC_ADDIB_SN,
-  TILE_OPC_ADDIH,
-  TILE_OPC_ADDIH_SN,
-  TILE_OPC_ADDLI,
-  TILE_OPC_ADDLI_SN,
-  TILE_OPC_ADDLIS,
-  TILE_OPC_ADDS,
-  TILE_OPC_ADDS_SN,
-  TILE_OPC_ADIFFB_U,
-  TILE_OPC_ADIFFB_U_SN,
-  TILE_OPC_ADIFFH,
-  TILE_OPC_ADIFFH_SN,
-  TILE_OPC_AND,
-  TILE_OPC_AND_SN,
-  TILE_OPC_ANDI,
-  TILE_OPC_ANDI_SN,
-  TILE_OPC_AULI,
-  TILE_OPC_AVGB_U,
-  TILE_OPC_AVGB_U_SN,
-  TILE_OPC_AVGH,
-  TILE_OPC_AVGH_SN,
-  TILE_OPC_BBNS,
-  TILE_OPC_BBNS_SN,
-  TILE_OPC_BBNST,
-  TILE_OPC_BBNST_SN,
-  TILE_OPC_BBS,
-  TILE_OPC_BBS_SN,
-  TILE_OPC_BBST,
-  TILE_OPC_BBST_SN,
-  TILE_OPC_BGEZ,
-  TILE_OPC_BGEZ_SN,
-  TILE_OPC_BGEZT,
-  TILE_OPC_BGEZT_SN,
-  TILE_OPC_BGZ,
-  TILE_OPC_BGZ_SN,
-  TILE_OPC_BGZT,
-  TILE_OPC_BGZT_SN,
-  TILE_OPC_BITX,
-  TILE_OPC_BITX_SN,
-  TILE_OPC_BLEZ,
-  TILE_OPC_BLEZ_SN,
-  TILE_OPC_BLEZT,
-  TILE_OPC_BLEZT_SN,
-  TILE_OPC_BLZ,
-  TILE_OPC_BLZ_SN,
-  TILE_OPC_BLZT,
-  TILE_OPC_BLZT_SN,
-  TILE_OPC_BNZ,
-  TILE_OPC_BNZ_SN,
-  TILE_OPC_BNZT,
-  TILE_OPC_BNZT_SN,
-  TILE_OPC_BYTEX,
-  TILE_OPC_BYTEX_SN,
-  TILE_OPC_BZ,
-  TILE_OPC_BZ_SN,
-  TILE_OPC_BZT,
-  TILE_OPC_BZT_SN,
-  TILE_OPC_CLZ,
-  TILE_OPC_CLZ_SN,
-  TILE_OPC_CRC32_32,
-  TILE_OPC_CRC32_32_SN,
-  TILE_OPC_CRC32_8,
-  TILE_OPC_CRC32_8_SN,
-  TILE_OPC_CTZ,
-  TILE_OPC_CTZ_SN,
-  TILE_OPC_DRAIN,
-  TILE_OPC_DTLBPR,
-  TILE_OPC_DWORD_ALIGN,
-  TILE_OPC_DWORD_ALIGN_SN,
-  TILE_OPC_FINV,
-  TILE_OPC_FLUSH,
-  TILE_OPC_FNOP,
-  TILE_OPC_ICOH,
-  TILE_OPC_ILL,
-  TILE_OPC_INTHB,
-  TILE_OPC_INTHB_SN,
-  TILE_OPC_INTHH,
-  TILE_OPC_INTHH_SN,
-  TILE_OPC_INTLB,
-  TILE_OPC_INTLB_SN,
-  TILE_OPC_INTLH,
-  TILE_OPC_INTLH_SN,
-  TILE_OPC_INV,
-  TILE_OPC_IRET,
-  TILE_OPC_JALB,
-  TILE_OPC_JALF,
-  TILE_OPC_JALR,
-  TILE_OPC_JALRP,
-  TILE_OPC_JB,
-  TILE_OPC_JF,
-  TILE_OPC_JR,
-  TILE_OPC_JRP,
-  TILE_OPC_LB,
-  TILE_OPC_LB_SN,
-  TILE_OPC_LB_U,
-  TILE_OPC_LB_U_SN,
-  TILE_OPC_LBADD,
-  TILE_OPC_LBADD_SN,
-  TILE_OPC_LBADD_U,
-  TILE_OPC_LBADD_U_SN,
-  TILE_OPC_LH,
-  TILE_OPC_LH_SN,
-  TILE_OPC_LH_U,
-  TILE_OPC_LH_U_SN,
-  TILE_OPC_LHADD,
-  TILE_OPC_LHADD_SN,
-  TILE_OPC_LHADD_U,
-  TILE_OPC_LHADD_U_SN,
-  TILE_OPC_LNK,
-  TILE_OPC_LNK_SN,
-  TILE_OPC_LW,
-  TILE_OPC_LW_SN,
-  TILE_OPC_LW_NA,
-  TILE_OPC_LW_NA_SN,
-  TILE_OPC_LWADD,
-  TILE_OPC_LWADD_SN,
-  TILE_OPC_LWADD_NA,
-  TILE_OPC_LWADD_NA_SN,
-  TILE_OPC_MAXB_U,
-  TILE_OPC_MAXB_U_SN,
-  TILE_OPC_MAXH,
-  TILE_OPC_MAXH_SN,
-  TILE_OPC_MAXIB_U,
-  TILE_OPC_MAXIB_U_SN,
-  TILE_OPC_MAXIH,
-  TILE_OPC_MAXIH_SN,
-  TILE_OPC_MF,
-  TILE_OPC_MFSPR,
-  TILE_OPC_MINB_U,
-  TILE_OPC_MINB_U_SN,
-  TILE_OPC_MINH,
-  TILE_OPC_MINH_SN,
-  TILE_OPC_MINIB_U,
-  TILE_OPC_MINIB_U_SN,
-  TILE_OPC_MINIH,
-  TILE_OPC_MINIH_SN,
-  TILE_OPC_MM,
-  TILE_OPC_MNZ,
-  TILE_OPC_MNZ_SN,
-  TILE_OPC_MNZB,
-  TILE_OPC_MNZB_SN,
-  TILE_OPC_MNZH,
-  TILE_OPC_MNZH_SN,
-  TILE_OPC_MTSPR,
-  TILE_OPC_MULHH_SS,
-  TILE_OPC_MULHH_SS_SN,
-  TILE_OPC_MULHH_SU,
-  TILE_OPC_MULHH_SU_SN,
-  TILE_OPC_MULHH_UU,
-  TILE_OPC_MULHH_UU_SN,
-  TILE_OPC_MULHHA_SS,
-  TILE_OPC_MULHHA_SS_SN,
-  TILE_OPC_MULHHA_SU,
-  TILE_OPC_MULHHA_SU_SN,
-  TILE_OPC_MULHHA_UU,
-  TILE_OPC_MULHHA_UU_SN,
-  TILE_OPC_MULHHSA_UU,
-  TILE_OPC_MULHHSA_UU_SN,
-  TILE_OPC_MULHL_SS,
-  TILE_OPC_MULHL_SS_SN,
-  TILE_OPC_MULHL_SU,
-  TILE_OPC_MULHL_SU_SN,
-  TILE_OPC_MULHL_US,
-  TILE_OPC_MULHL_US_SN,
-  TILE_OPC_MULHL_UU,
-  TILE_OPC_MULHL_UU_SN,
-  TILE_OPC_MULHLA_SS,
-  TILE_OPC_MULHLA_SS_SN,
-  TILE_OPC_MULHLA_SU,
-  TILE_OPC_MULHLA_SU_SN,
-  TILE_OPC_MULHLA_US,
-  TILE_OPC_MULHLA_US_SN,
-  TILE_OPC_MULHLA_UU,
-  TILE_OPC_MULHLA_UU_SN,
-  TILE_OPC_MULHLSA_UU,
-  TILE_OPC_MULHLSA_UU_SN,
-  TILE_OPC_MULLL_SS,
-  TILE_OPC_MULLL_SS_SN,
-  TILE_OPC_MULLL_SU,
-  TILE_OPC_MULLL_SU_SN,
-  TILE_OPC_MULLL_UU,
-  TILE_OPC_MULLL_UU_SN,
-  TILE_OPC_MULLLA_SS,
-  TILE_OPC_MULLLA_SS_SN,
-  TILE_OPC_MULLLA_SU,
-  TILE_OPC_MULLLA_SU_SN,
-  TILE_OPC_MULLLA_UU,
-  TILE_OPC_MULLLA_UU_SN,
-  TILE_OPC_MULLLSA_UU,
-  TILE_OPC_MULLLSA_UU_SN,
-  TILE_OPC_MVNZ,
-  TILE_OPC_MVNZ_SN,
-  TILE_OPC_MVZ,
-  TILE_OPC_MVZ_SN,
-  TILE_OPC_MZ,
-  TILE_OPC_MZ_SN,
-  TILE_OPC_MZB,
-  TILE_OPC_MZB_SN,
-  TILE_OPC_MZH,
-  TILE_OPC_MZH_SN,
-  TILE_OPC_NAP,
-  TILE_OPC_NOP,
-  TILE_OPC_NOR,
-  TILE_OPC_NOR_SN,
-  TILE_OPC_OR,
-  TILE_OPC_OR_SN,
-  TILE_OPC_ORI,
-  TILE_OPC_ORI_SN,
-  TILE_OPC_PACKBS_U,
-  TILE_OPC_PACKBS_U_SN,
-  TILE_OPC_PACKHB,
-  TILE_OPC_PACKHB_SN,
-  TILE_OPC_PACKHS,
-  TILE_OPC_PACKHS_SN,
-  TILE_OPC_PACKLB,
-  TILE_OPC_PACKLB_SN,
-  TILE_OPC_PCNT,
-  TILE_OPC_PCNT_SN,
-  TILE_OPC_RL,
-  TILE_OPC_RL_SN,
-  TILE_OPC_RLI,
-  TILE_OPC_RLI_SN,
-  TILE_OPC_S1A,
-  TILE_OPC_S1A_SN,
-  TILE_OPC_S2A,
-  TILE_OPC_S2A_SN,
-  TILE_OPC_S3A,
-  TILE_OPC_S3A_SN,
-  TILE_OPC_SADAB_U,
-  TILE_OPC_SADAB_U_SN,
-  TILE_OPC_SADAH,
-  TILE_OPC_SADAH_SN,
-  TILE_OPC_SADAH_U,
-  TILE_OPC_SADAH_U_SN,
-  TILE_OPC_SADB_U,
-  TILE_OPC_SADB_U_SN,
-  TILE_OPC_SADH,
-  TILE_OPC_SADH_SN,
-  TILE_OPC_SADH_U,
-  TILE_OPC_SADH_U_SN,
-  TILE_OPC_SB,
-  TILE_OPC_SBADD,
-  TILE_OPC_SEQ,
-  TILE_OPC_SEQ_SN,
-  TILE_OPC_SEQB,
-  TILE_OPC_SEQB_SN,
-  TILE_OPC_SEQH,
-  TILE_OPC_SEQH_SN,
-  TILE_OPC_SEQI,
-  TILE_OPC_SEQI_SN,
-  TILE_OPC_SEQIB,
-  TILE_OPC_SEQIB_SN,
-  TILE_OPC_SEQIH,
-  TILE_OPC_SEQIH_SN,
-  TILE_OPC_SH,
-  TILE_OPC_SHADD,
-  TILE_OPC_SHL,
-  TILE_OPC_SHL_SN,
-  TILE_OPC_SHLB,
-  TILE_OPC_SHLB_SN,
-  TILE_OPC_SHLH,
-  TILE_OPC_SHLH_SN,
-  TILE_OPC_SHLI,
-  TILE_OPC_SHLI_SN,
-  TILE_OPC_SHLIB,
-  TILE_OPC_SHLIB_SN,
-  TILE_OPC_SHLIH,
-  TILE_OPC_SHLIH_SN,
-  TILE_OPC_SHR,
-  TILE_OPC_SHR_SN,
-  TILE_OPC_SHRB,
-  TILE_OPC_SHRB_SN,
-  TILE_OPC_SHRH,
-  TILE_OPC_SHRH_SN,
-  TILE_OPC_SHRI,
-  TILE_OPC_SHRI_SN,
-  TILE_OPC_SHRIB,
-  TILE_OPC_SHRIB_SN,
-  TILE_OPC_SHRIH,
-  TILE_OPC_SHRIH_SN,
-  TILE_OPC_SLT,
-  TILE_OPC_SLT_SN,
-  TILE_OPC_SLT_U,
-  TILE_OPC_SLT_U_SN,
-  TILE_OPC_SLTB,
-  TILE_OPC_SLTB_SN,
-  TILE_OPC_SLTB_U,
-  TILE_OPC_SLTB_U_SN,
-  TILE_OPC_SLTE,
-  TILE_OPC_SLTE_SN,
-  TILE_OPC_SLTE_U,
-  TILE_OPC_SLTE_U_SN,
-  TILE_OPC_SLTEB,
-  TILE_OPC_SLTEB_SN,
-  TILE_OPC_SLTEB_U,
-  TILE_OPC_SLTEB_U_SN,
-  TILE_OPC_SLTEH,
-  TILE_OPC_SLTEH_SN,
-  TILE_OPC_SLTEH_U,
-  TILE_OPC_SLTEH_U_SN,
-  TILE_OPC_SLTH,
-  TILE_OPC_SLTH_SN,
-  TILE_OPC_SLTH_U,
-  TILE_OPC_SLTH_U_SN,
-  TILE_OPC_SLTI,
-  TILE_OPC_SLTI_SN,
-  TILE_OPC_SLTI_U,
-  TILE_OPC_SLTI_U_SN,
-  TILE_OPC_SLTIB,
-  TILE_OPC_SLTIB_SN,
-  TILE_OPC_SLTIB_U,
-  TILE_OPC_SLTIB_U_SN,
-  TILE_OPC_SLTIH,
-  TILE_OPC_SLTIH_SN,
-  TILE_OPC_SLTIH_U,
-  TILE_OPC_SLTIH_U_SN,
-  TILE_OPC_SNE,
-  TILE_OPC_SNE_SN,
-  TILE_OPC_SNEB,
-  TILE_OPC_SNEB_SN,
-  TILE_OPC_SNEH,
-  TILE_OPC_SNEH_SN,
-  TILE_OPC_SRA,
-  TILE_OPC_SRA_SN,
-  TILE_OPC_SRAB,
-  TILE_OPC_SRAB_SN,
-  TILE_OPC_SRAH,
-  TILE_OPC_SRAH_SN,
-  TILE_OPC_SRAI,
-  TILE_OPC_SRAI_SN,
-  TILE_OPC_SRAIB,
-  TILE_OPC_SRAIB_SN,
-  TILE_OPC_SRAIH,
-  TILE_OPC_SRAIH_SN,
-  TILE_OPC_SUB,
-  TILE_OPC_SUB_SN,
-  TILE_OPC_SUBB,
-  TILE_OPC_SUBB_SN,
-  TILE_OPC_SUBBS_U,
-  TILE_OPC_SUBBS_U_SN,
-  TILE_OPC_SUBH,
-  TILE_OPC_SUBH_SN,
-  TILE_OPC_SUBHS,
-  TILE_OPC_SUBHS_SN,
-  TILE_OPC_SUBS,
-  TILE_OPC_SUBS_SN,
-  TILE_OPC_SW,
-  TILE_OPC_SWADD,
-  TILE_OPC_SWINT0,
-  TILE_OPC_SWINT1,
-  TILE_OPC_SWINT2,
-  TILE_OPC_SWINT3,
-  TILE_OPC_TBLIDXB0,
-  TILE_OPC_TBLIDXB0_SN,
-  TILE_OPC_TBLIDXB1,
-  TILE_OPC_TBLIDXB1_SN,
-  TILE_OPC_TBLIDXB2,
-  TILE_OPC_TBLIDXB2_SN,
-  TILE_OPC_TBLIDXB3,
-  TILE_OPC_TBLIDXB3_SN,
-  TILE_OPC_TNS,
-  TILE_OPC_TNS_SN,
-  TILE_OPC_WH64,
-  TILE_OPC_XOR,
-  TILE_OPC_XOR_SN,
-  TILE_OPC_XORI,
-  TILE_OPC_XORI_SN,
-  TILE_OPC_NONE
-} tile_mnemonic;
-
-/* 64-bit pattern for a { bpt ; nop } bundle. */
-#define TILE_BPT_BUNDLE 0x400b3cae70166000ULL
-
-
-#define TILE_ELF_MACHINE_CODE EM_TILEPRO
-
-#define TILE_ELF_NAME "elf32-tilepro"
-
-
-static __inline unsigned int
-get_BrOff_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_BrOff_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x00007fff) |
-         (((unsigned int)(n >> 20)) & 0x00018000);
-}
-
-static __inline unsigned int
-get_BrType_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0xf);
-}
-
-static __inline unsigned int
-get_Dest_Imm8_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x0000003f) |
-         (((unsigned int)(n >> 43)) & 0x000000c0);
-}
-
-static __inline unsigned int
-get_Dest_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 2)) & 0x3);
-}
-
-static __inline unsigned int
-get_Dest_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_Y0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Imm16_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0xffff);
-}
-
-static __inline unsigned int
-get_Imm16_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0xffff);
-}
-
-static __inline unsigned int
-get_Imm8_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_Y0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0xff);
-}
-
-static __inline unsigned int
-get_ImmOpcodeExtension_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 20)) & 0x7f);
-}
-
-static __inline unsigned int
-get_ImmOpcodeExtension_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 51)) & 0x7f);
-}
-
-static __inline unsigned int
-get_ImmRROpcodeExtension_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 8)) & 0x3);
-}
-
-static __inline unsigned int
-get_JOffLong_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x00007fff) |
-         (((unsigned int)(n >> 20)) & 0x00018000) |
-         (((unsigned int)(n >> 14)) & 0x001e0000) |
-         (((unsigned int)(n >> 16)) & 0x07e00000) |
-         (((unsigned int)(n >> 31)) & 0x18000000);
-}
-
-static __inline unsigned int
-get_JOff_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x00007fff) |
-         (((unsigned int)(n >> 20)) & 0x00018000) |
-         (((unsigned int)(n >> 14)) & 0x001e0000) |
-         (((unsigned int)(n >> 16)) & 0x07e00000) |
-         (((unsigned int)(n >> 31)) & 0x08000000);
-}
-
-static __inline unsigned int
-get_MF_Imm15_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 37)) & 0x00003fff) |
-         (((unsigned int)(n >> 44)) & 0x00004000);
-}
-
-static __inline unsigned int
-get_MMEnd_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x1f);
-}
-
-static __inline unsigned int
-get_MMEnd_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 49)) & 0x1f);
-}
-
-static __inline unsigned int
-get_MMStart_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 23)) & 0x1f);
-}
-
-static __inline unsigned int
-get_MMStart_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 54)) & 0x1f);
-}
-
-static __inline unsigned int
-get_MT_Imm15_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x0000003f) |
-         (((unsigned int)(n >> 37)) & 0x00003fc0) |
-         (((unsigned int)(n >> 44)) & 0x00004000);
-}
-
-static __inline unsigned int
-get_Mode(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 63)) & 0x1);
-}
-
-static __inline unsigned int
-get_NoRegOpcodeExtension_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 10)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Opcode_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 28)) & 0x7);
-}
-
-static __inline unsigned int
-get_Opcode_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 59)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 27)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 59)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y2(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 56)) & 0x7);
-}
-
-static __inline unsigned int
-get_RROpcodeExtension_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 4)) & 0xf);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x1ff);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 49)) & 0x1ff);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_Y0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x3);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 49)) & 0x3);
-}
-
-static __inline unsigned int
-get_RouteOpcodeExtension_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_S_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 27)) & 0x1);
-}
-
-static __inline unsigned int
-get_S_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 58)) & 0x1);
-}
-
-static __inline unsigned int
-get_ShAmt_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x1f);
-}
-
-static __inline unsigned int
-get_ShAmt_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x1f);
-}
-
-static __inline unsigned int
-get_ShAmt_Y0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x1f);
-}
-
-static __inline unsigned int
-get_ShAmt_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x1f);
-}
-
-static __inline unsigned int
-get_SrcA_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 6)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 37)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 6)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 37)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y2(tile_bundle_bits n)
-{
-  return (((n >> 26)) & 0x00000001) |
-         (((unsigned int)(n >> 50)) & 0x0000003e);
-}
-
-static __inline unsigned int
-get_SrcBDest_Y2(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 20)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_Y0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Src_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3);
-}
-
-static __inline unsigned int
-get_UnOpcodeExtension_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x1f);
-}
-
-static __inline unsigned int
-get_UnOpcodeExtension_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x1f);
-}
-
-static __inline unsigned int
-get_UnOpcodeExtension_Y0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x1f);
-}
-
-static __inline unsigned int
-get_UnOpcodeExtension_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x1f);
-}
-
-static __inline unsigned int
-get_UnShOpcodeExtension_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 17)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_UnShOpcodeExtension_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 48)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_UnShOpcodeExtension_Y0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 17)) & 0x7);
-}
-
-static __inline unsigned int
-get_UnShOpcodeExtension_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 48)) & 0x7);
-}
-
-
-static __inline int
-sign_extend(int n, int num_bits)
-{
-  int shift = (int)(sizeof(int) * 8 - num_bits);
-  return (n << shift) >> shift;
-}
-
-
-
-static __inline tile_bundle_bits
-create_BrOff_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3ff) << 0);
-}
-
-static __inline tile_bundle_bits
-create_BrOff_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
-         (((tile_bundle_bits)(n & 0x00018000)) << 20);
-}
-
-static __inline tile_bundle_bits
-create_BrType_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xf)) << 31);
-}
-
-static __inline tile_bundle_bits
-create_Dest_Imm8_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
-         (((tile_bundle_bits)(n & 0x000000c0)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_Dest_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3) << 2);
-}
-
-static __inline tile_bundle_bits
-create_Dest_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 0);
-}
-
-static __inline tile_bundle_bits
-create_Dest_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 31);
-}
-
-static __inline tile_bundle_bits
-create_Dest_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 0);
-}
-
-static __inline tile_bundle_bits
-create_Dest_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 31);
-}
-
-static __inline tile_bundle_bits
-create_Imm16_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xffff) << 12);
-}
-
-static __inline tile_bundle_bits
-create_Imm16_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xffff)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_Imm8_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xff) << 0);
-}
-
-static __inline tile_bundle_bits
-create_Imm8_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xff) << 12);
-}
-
-static __inline tile_bundle_bits
-create_Imm8_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xff)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_Imm8_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xff) << 12);
-}
-
-static __inline tile_bundle_bits
-create_Imm8_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xff)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_ImmOpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x7f) << 20);
-}
-
-static __inline tile_bundle_bits
-create_ImmOpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x7f)) << 51);
-}
-
-static __inline tile_bundle_bits
-create_ImmRROpcodeExtension_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3) << 8);
-}
-
-static __inline tile_bundle_bits
-create_JOffLong_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
-         (((tile_bundle_bits)(n & 0x00018000)) << 20) |
-         (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
-         (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
-         (((tile_bundle_bits)(n & 0x18000000)) << 31);
-}
-
-static __inline tile_bundle_bits
-create_JOff_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
-         (((tile_bundle_bits)(n & 0x00018000)) << 20) |
-         (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
-         (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
-         (((tile_bundle_bits)(n & 0x08000000)) << 31);
-}
-
-static __inline tile_bundle_bits
-create_MF_Imm15_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x00003fff)) << 37) |
-         (((tile_bundle_bits)(n & 0x00004000)) << 44);
-}
-
-static __inline tile_bundle_bits
-create_MMEnd_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 18);
-}
-
-static __inline tile_bundle_bits
-create_MMEnd_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 49);
-}
-
-static __inline tile_bundle_bits
-create_MMStart_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 23);
-}
-
-static __inline tile_bundle_bits
-create_MMStart_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 54);
-}
-
-static __inline tile_bundle_bits
-create_MT_Imm15_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
-         (((tile_bundle_bits)(n & 0x00003fc0)) << 37) |
-         (((tile_bundle_bits)(n & 0x00004000)) << 44);
-}
-
-static __inline tile_bundle_bits
-create_Mode(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1)) << 63);
-}
-
-static __inline tile_bundle_bits
-create_NoRegOpcodeExtension_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xf) << 0);
-}
-
-static __inline tile_bundle_bits
-create_Opcode_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 10);
-}
-
-static __inline tile_bundle_bits
-create_Opcode_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x7) << 28);
-}
-
-static __inline tile_bundle_bits
-create_Opcode_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xf)) << 59);
-}
-
-static __inline tile_bundle_bits
-create_Opcode_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xf) << 27);
-}
-
-static __inline tile_bundle_bits
-create_Opcode_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xf)) << 59);
-}
-
-static __inline tile_bundle_bits
-create_Opcode_Y2(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x7)) << 56);
-}
-
-static __inline tile_bundle_bits
-create_RROpcodeExtension_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xf) << 4);
-}
-
-static __inline tile_bundle_bits
-create_RRROpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1ff) << 18);
-}
-
-static __inline tile_bundle_bits
-create_RRROpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1ff)) << 49);
-}
-
-static __inline tile_bundle_bits
-create_RRROpcodeExtension_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3) << 18);
-}
-
-static __inline tile_bundle_bits
-create_RRROpcodeExtension_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3)) << 49);
-}
-
-static __inline tile_bundle_bits
-create_RouteOpcodeExtension_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3ff) << 0);
-}
-
-static __inline tile_bundle_bits
-create_S_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1) << 27);
-}
-
-static __inline tile_bundle_bits
-create_S_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1)) << 58);
-}
-
-static __inline tile_bundle_bits
-create_ShAmt_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 12);
-}
-
-static __inline tile_bundle_bits
-create_ShAmt_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_ShAmt_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 12);
-}
-
-static __inline tile_bundle_bits
-create_ShAmt_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_SrcA_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 6);
-}
-
-static __inline tile_bundle_bits
-create_SrcA_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 37);
-}
-
-static __inline tile_bundle_bits
-create_SrcA_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 6);
-}
-
-static __inline tile_bundle_bits
-create_SrcA_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 37);
-}
-
-static __inline tile_bundle_bits
-create_SrcA_Y2(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x00000001) << 26) |
-         (((tile_bundle_bits)(n & 0x0000003e)) << 50);
-}
-
-static __inline tile_bundle_bits
-create_SrcBDest_Y2(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 20);
-}
-
-static __inline tile_bundle_bits
-create_SrcB_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 12);
-}
-
-static __inline tile_bundle_bits
-create_SrcB_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_SrcB_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 12);
-}
-
-static __inline tile_bundle_bits
-create_SrcB_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_Src_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3) << 0);
-}
-
-static __inline tile_bundle_bits
-create_UnOpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 12);
-}
-
-static __inline tile_bundle_bits
-create_UnOpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_UnOpcodeExtension_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 12);
-}
-
-static __inline tile_bundle_bits
-create_UnOpcodeExtension_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_UnShOpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3ff) << 17);
-}
-
-static __inline tile_bundle_bits
-create_UnShOpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3ff)) << 48);
-}
-
-static __inline tile_bundle_bits
-create_UnShOpcodeExtension_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x7) << 17);
-}
-
-static __inline tile_bundle_bits
-create_UnShOpcodeExtension_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x7)) << 48);
-}
-
-
-
-typedef enum
-{
-  TILE_PIPELINE_X0,
-  TILE_PIPELINE_X1,
-  TILE_PIPELINE_Y0,
-  TILE_PIPELINE_Y1,
-  TILE_PIPELINE_Y2,
-} tile_pipeline;
-
-#define tile_is_x_pipeline(p) ((int)(p) <= (int)TILE_PIPELINE_X1)
-
-typedef enum
-{
-  TILE_OP_TYPE_REGISTER,
-  TILE_OP_TYPE_IMMEDIATE,
-  TILE_OP_TYPE_ADDRESS,
-  TILE_OP_TYPE_SPR
-} tile_operand_type;
-
-/* This is the bit that determines if a bundle is in the Y encoding. */
-#define TILE_BUNDLE_Y_ENCODING_MASK ((tile_bundle_bits)1 << 63)
-
-enum
-{
-  /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
-  TILE_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
-
-  /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
-  TILE_NUM_PIPELINE_ENCODINGS = 5,
-
-  /* Log base 2 of TILE_BUNDLE_SIZE_IN_BYTES. */
-  TILE_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
-
-  /* Instructions take this many bytes. */
-  TILE_BUNDLE_SIZE_IN_BYTES = 1 << TILE_LOG2_BUNDLE_SIZE_IN_BYTES,
-
-  /* Log base 2 of TILE_BUNDLE_ALIGNMENT_IN_BYTES. */
-  TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
-
-  /* Bundles should be aligned modulo this number of bytes. */
-  TILE_BUNDLE_ALIGNMENT_IN_BYTES =
-    (1 << TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
-
-  /* Log base 2 of TILE_SN_INSTRUCTION_SIZE_IN_BYTES. */
-  TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES = 1,
-
-  /* Static network instructions take this many bytes. */
-  TILE_SN_INSTRUCTION_SIZE_IN_BYTES =
-    (1 << TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES),
-
-  /* Number of registers (some are magic, such as network I/O). */
-  TILE_NUM_REGISTERS = 64,
-
-  /* Number of static network registers. */
-  TILE_NUM_SN_REGISTERS = 4
-};
-
-
-struct tile_operand
-{
-  /* Is this operand a register, immediate or address? */
-  tile_operand_type type;
-
-  /* The default relocation type for this operand.  */
-  signed int default_reloc : 16;
-
-  /* How many bits is this value? (used for range checking) */
-  unsigned int num_bits : 5;
-
-  /* Is the value signed? (used for range checking) */
-  unsigned int is_signed : 1;
-
-  /* Is this operand a source register? */
-  unsigned int is_src_reg : 1;
-
-  /* Is this operand written? (i.e. is it a destination register) */
-  unsigned int is_dest_reg : 1;
-
-  /* Is this operand PC-relative? */
-  unsigned int is_pc_relative : 1;
-
-  /* By how many bits do we right shift the value before inserting? */
-  unsigned int rightshift : 2;
-
-  /* Return the bits for this operand to be ORed into an existing bundle. */
-  tile_bundle_bits (*insert) (int op);
-
-  /* Extract this operand and return it. */
-  unsigned int (*extract) (tile_bundle_bits bundle);
-};
-
-
-extern const struct tile_operand tile_operands[];
-
-/* One finite-state machine per pipe for rapid instruction decoding. */
-extern const unsigned short * const
-tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS];
-
-
-struct tile_opcode
-{
-  /* The opcode mnemonic, e.g. "add" */
-  const char *name;
-
-  /* The enum value for this mnemonic. */
-  tile_mnemonic mnemonic;
-
-  /* A bit mask of which of the five pipes this instruction
-     is compatible with:
-     X0  0x01
-     X1  0x02
-     Y0  0x04
-     Y1  0x08
-     Y2  0x10 */
-  unsigned char pipes;
-
-  /* How many operands are there? */
-  unsigned char num_operands;
-
-  /* Which register does this write implicitly, or TREG_ZERO if none? */
-  unsigned char implicitly_written_register;
-
-  /* Can this be bundled with other instructions (almost always true). */
-  unsigned char can_bundle;
-
-  /* The description of the operands. Each of these is an
-   * index into the tile_operands[] table. */
-  unsigned char operands[TILE_NUM_PIPELINE_ENCODINGS][TILE_MAX_OPERANDS];
-
-};
-
-extern const struct tile_opcode tile_opcodes[];
-
-
-/* Used for non-textual disassembly into structs. */
-struct tile_decoded_instruction
-{
-  const struct tile_opcode *opcode;
-  const struct tile_operand *operands[TILE_MAX_OPERANDS];
-  int operand_values[TILE_MAX_OPERANDS];
-};
-
-
-/* Disassemble a bundle into a struct for machine processing. */
-extern int parse_insn_tile(tile_bundle_bits bits,
-                           unsigned int pc,
-                           struct tile_decoded_instruction
-                           decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
-
-
-/* Given a set of bundle bits and a specific pipe, returns which
- * instruction the bundle contains in that pipe.
- */
-extern const struct tile_opcode *
-find_opcode(tile_bundle_bits bits, tile_pipeline pipe);
-
-
-
-#endif /* opcode_tile_h */
diff --git a/arch/tile/include/asm/opcode-tile_64.h b/arch/tile/include/asm/opcode-tile_64.h
deleted file mode 100644 (file)
index c063346..0000000
+++ /dev/null
@@ -1,1248 +0,0 @@
-/* tile.h -- Header file for TILE opcode table
-   Copyright (C) 2005 Free Software Foundation, Inc.
-   Contributed by Tilera Corp. */
-
-#ifndef opcode_tile_h
-#define opcode_tile_h
-
-typedef unsigned long long tilegx_bundle_bits;
-
-
-enum
-{
-  TILEGX_MAX_OPERANDS = 4 /* bfexts */
-};
-
-typedef enum
-{
-  TILEGX_OPC_BPT,
-  TILEGX_OPC_INFO,
-  TILEGX_OPC_INFOL,
-  TILEGX_OPC_MOVE,
-  TILEGX_OPC_MOVEI,
-  TILEGX_OPC_MOVELI,
-  TILEGX_OPC_PREFETCH,
-  TILEGX_OPC_PREFETCH_ADD_L1,
-  TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
-  TILEGX_OPC_PREFETCH_ADD_L2,
-  TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
-  TILEGX_OPC_PREFETCH_ADD_L3,
-  TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
-  TILEGX_OPC_PREFETCH_L1,
-  TILEGX_OPC_PREFETCH_L1_FAULT,
-  TILEGX_OPC_PREFETCH_L2,
-  TILEGX_OPC_PREFETCH_L2_FAULT,
-  TILEGX_OPC_PREFETCH_L3,
-  TILEGX_OPC_PREFETCH_L3_FAULT,
-  TILEGX_OPC_RAISE,
-  TILEGX_OPC_ADD,
-  TILEGX_OPC_ADDI,
-  TILEGX_OPC_ADDLI,
-  TILEGX_OPC_ADDX,
-  TILEGX_OPC_ADDXI,
-  TILEGX_OPC_ADDXLI,
-  TILEGX_OPC_ADDXSC,
-  TILEGX_OPC_AND,
-  TILEGX_OPC_ANDI,
-  TILEGX_OPC_BEQZ,
-  TILEGX_OPC_BEQZT,
-  TILEGX_OPC_BFEXTS,
-  TILEGX_OPC_BFEXTU,
-  TILEGX_OPC_BFINS,
-  TILEGX_OPC_BGEZ,
-  TILEGX_OPC_BGEZT,
-  TILEGX_OPC_BGTZ,
-  TILEGX_OPC_BGTZT,
-  TILEGX_OPC_BLBC,
-  TILEGX_OPC_BLBCT,
-  TILEGX_OPC_BLBS,
-  TILEGX_OPC_BLBST,
-  TILEGX_OPC_BLEZ,
-  TILEGX_OPC_BLEZT,
-  TILEGX_OPC_BLTZ,
-  TILEGX_OPC_BLTZT,
-  TILEGX_OPC_BNEZ,
-  TILEGX_OPC_BNEZT,
-  TILEGX_OPC_CLZ,
-  TILEGX_OPC_CMOVEQZ,
-  TILEGX_OPC_CMOVNEZ,
-  TILEGX_OPC_CMPEQ,
-  TILEGX_OPC_CMPEQI,
-  TILEGX_OPC_CMPEXCH,
-  TILEGX_OPC_CMPEXCH4,
-  TILEGX_OPC_CMPLES,
-  TILEGX_OPC_CMPLEU,
-  TILEGX_OPC_CMPLTS,
-  TILEGX_OPC_CMPLTSI,
-  TILEGX_OPC_CMPLTU,
-  TILEGX_OPC_CMPLTUI,
-  TILEGX_OPC_CMPNE,
-  TILEGX_OPC_CMUL,
-  TILEGX_OPC_CMULA,
-  TILEGX_OPC_CMULAF,
-  TILEGX_OPC_CMULF,
-  TILEGX_OPC_CMULFR,
-  TILEGX_OPC_CMULH,
-  TILEGX_OPC_CMULHR,
-  TILEGX_OPC_CRC32_32,
-  TILEGX_OPC_CRC32_8,
-  TILEGX_OPC_CTZ,
-  TILEGX_OPC_DBLALIGN,
-  TILEGX_OPC_DBLALIGN2,
-  TILEGX_OPC_DBLALIGN4,
-  TILEGX_OPC_DBLALIGN6,
-  TILEGX_OPC_DRAIN,
-  TILEGX_OPC_DTLBPR,
-  TILEGX_OPC_EXCH,
-  TILEGX_OPC_EXCH4,
-  TILEGX_OPC_FDOUBLE_ADD_FLAGS,
-  TILEGX_OPC_FDOUBLE_ADDSUB,
-  TILEGX_OPC_FDOUBLE_MUL_FLAGS,
-  TILEGX_OPC_FDOUBLE_PACK1,
-  TILEGX_OPC_FDOUBLE_PACK2,
-  TILEGX_OPC_FDOUBLE_SUB_FLAGS,
-  TILEGX_OPC_FDOUBLE_UNPACK_MAX,
-  TILEGX_OPC_FDOUBLE_UNPACK_MIN,
-  TILEGX_OPC_FETCHADD,
-  TILEGX_OPC_FETCHADD4,
-  TILEGX_OPC_FETCHADDGEZ,
-  TILEGX_OPC_FETCHADDGEZ4,
-  TILEGX_OPC_FETCHAND,
-  TILEGX_OPC_FETCHAND4,
-  TILEGX_OPC_FETCHOR,
-  TILEGX_OPC_FETCHOR4,
-  TILEGX_OPC_FINV,
-  TILEGX_OPC_FLUSH,
-  TILEGX_OPC_FLUSHWB,
-  TILEGX_OPC_FNOP,
-  TILEGX_OPC_FSINGLE_ADD1,
-  TILEGX_OPC_FSINGLE_ADDSUB2,
-  TILEGX_OPC_FSINGLE_MUL1,
-  TILEGX_OPC_FSINGLE_MUL2,
-  TILEGX_OPC_FSINGLE_PACK1,
-  TILEGX_OPC_FSINGLE_PACK2,
-  TILEGX_OPC_FSINGLE_SUB1,
-  TILEGX_OPC_ICOH,
-  TILEGX_OPC_ILL,
-  TILEGX_OPC_INV,
-  TILEGX_OPC_IRET,
-  TILEGX_OPC_J,
-  TILEGX_OPC_JAL,
-  TILEGX_OPC_JALR,
-  TILEGX_OPC_JALRP,
-  TILEGX_OPC_JR,
-  TILEGX_OPC_JRP,
-  TILEGX_OPC_LD,
-  TILEGX_OPC_LD1S,
-  TILEGX_OPC_LD1S_ADD,
-  TILEGX_OPC_LD1U,
-  TILEGX_OPC_LD1U_ADD,
-  TILEGX_OPC_LD2S,
-  TILEGX_OPC_LD2S_ADD,
-  TILEGX_OPC_LD2U,
-  TILEGX_OPC_LD2U_ADD,
-  TILEGX_OPC_LD4S,
-  TILEGX_OPC_LD4S_ADD,
-  TILEGX_OPC_LD4U,
-  TILEGX_OPC_LD4U_ADD,
-  TILEGX_OPC_LD_ADD,
-  TILEGX_OPC_LDNA,
-  TILEGX_OPC_LDNA_ADD,
-  TILEGX_OPC_LDNT,
-  TILEGX_OPC_LDNT1S,
-  TILEGX_OPC_LDNT1S_ADD,
-  TILEGX_OPC_LDNT1U,
-  TILEGX_OPC_LDNT1U_ADD,
-  TILEGX_OPC_LDNT2S,
-  TILEGX_OPC_LDNT2S_ADD,
-  TILEGX_OPC_LDNT2U,
-  TILEGX_OPC_LDNT2U_ADD,
-  TILEGX_OPC_LDNT4S,
-  TILEGX_OPC_LDNT4S_ADD,
-  TILEGX_OPC_LDNT4U,
-  TILEGX_OPC_LDNT4U_ADD,
-  TILEGX_OPC_LDNT_ADD,
-  TILEGX_OPC_LNK,
-  TILEGX_OPC_MF,
-  TILEGX_OPC_MFSPR,
-  TILEGX_OPC_MM,
-  TILEGX_OPC_MNZ,
-  TILEGX_OPC_MTSPR,
-  TILEGX_OPC_MUL_HS_HS,
-  TILEGX_OPC_MUL_HS_HU,
-  TILEGX_OPC_MUL_HS_LS,
-  TILEGX_OPC_MUL_HS_LU,
-  TILEGX_OPC_MUL_HU_HU,
-  TILEGX_OPC_MUL_HU_LS,
-  TILEGX_OPC_MUL_HU_LU,
-  TILEGX_OPC_MUL_LS_LS,
-  TILEGX_OPC_MUL_LS_LU,
-  TILEGX_OPC_MUL_LU_LU,
-  TILEGX_OPC_MULA_HS_HS,
-  TILEGX_OPC_MULA_HS_HU,
-  TILEGX_OPC_MULA_HS_LS,
-  TILEGX_OPC_MULA_HS_LU,
-  TILEGX_OPC_MULA_HU_HU,
-  TILEGX_OPC_MULA_HU_LS,
-  TILEGX_OPC_MULA_HU_LU,
-  TILEGX_OPC_MULA_LS_LS,
-  TILEGX_OPC_MULA_LS_LU,
-  TILEGX_OPC_MULA_LU_LU,
-  TILEGX_OPC_MULAX,
-  TILEGX_OPC_MULX,
-  TILEGX_OPC_MZ,
-  TILEGX_OPC_NAP,
-  TILEGX_OPC_NOP,
-  TILEGX_OPC_NOR,
-  TILEGX_OPC_OR,
-  TILEGX_OPC_ORI,
-  TILEGX_OPC_PCNT,
-  TILEGX_OPC_REVBITS,
-  TILEGX_OPC_REVBYTES,
-  TILEGX_OPC_ROTL,
-  TILEGX_OPC_ROTLI,
-  TILEGX_OPC_SHL,
-  TILEGX_OPC_SHL16INSLI,
-  TILEGX_OPC_SHL1ADD,
-  TILEGX_OPC_SHL1ADDX,
-  TILEGX_OPC_SHL2ADD,
-  TILEGX_OPC_SHL2ADDX,
-  TILEGX_OPC_SHL3ADD,
-  TILEGX_OPC_SHL3ADDX,
-  TILEGX_OPC_SHLI,
-  TILEGX_OPC_SHLX,
-  TILEGX_OPC_SHLXI,
-  TILEGX_OPC_SHRS,
-  TILEGX_OPC_SHRSI,
-  TILEGX_OPC_SHRU,
-  TILEGX_OPC_SHRUI,
-  TILEGX_OPC_SHRUX,
-  TILEGX_OPC_SHRUXI,
-  TILEGX_OPC_SHUFFLEBYTES,
-  TILEGX_OPC_ST,
-  TILEGX_OPC_ST1,
-  TILEGX_OPC_ST1_ADD,
-  TILEGX_OPC_ST2,
-  TILEGX_OPC_ST2_ADD,
-  TILEGX_OPC_ST4,
-  TILEGX_OPC_ST4_ADD,
-  TILEGX_OPC_ST_ADD,
-  TILEGX_OPC_STNT,
-  TILEGX_OPC_STNT1,
-  TILEGX_OPC_STNT1_ADD,
-  TILEGX_OPC_STNT2,
-  TILEGX_OPC_STNT2_ADD,
-  TILEGX_OPC_STNT4,
-  TILEGX_OPC_STNT4_ADD,
-  TILEGX_OPC_STNT_ADD,
-  TILEGX_OPC_SUB,
-  TILEGX_OPC_SUBX,
-  TILEGX_OPC_SUBXSC,
-  TILEGX_OPC_SWINT0,
-  TILEGX_OPC_SWINT1,
-  TILEGX_OPC_SWINT2,
-  TILEGX_OPC_SWINT3,
-  TILEGX_OPC_TBLIDXB0,
-  TILEGX_OPC_TBLIDXB1,
-  TILEGX_OPC_TBLIDXB2,
-  TILEGX_OPC_TBLIDXB3,
-  TILEGX_OPC_V1ADD,
-  TILEGX_OPC_V1ADDI,
-  TILEGX_OPC_V1ADDUC,
-  TILEGX_OPC_V1ADIFFU,
-  TILEGX_OPC_V1AVGU,
-  TILEGX_OPC_V1CMPEQ,
-  TILEGX_OPC_V1CMPEQI,
-  TILEGX_OPC_V1CMPLES,
-  TILEGX_OPC_V1CMPLEU,
-  TILEGX_OPC_V1CMPLTS,
-  TILEGX_OPC_V1CMPLTSI,
-  TILEGX_OPC_V1CMPLTU,
-  TILEGX_OPC_V1CMPLTUI,
-  TILEGX_OPC_V1CMPNE,
-  TILEGX_OPC_V1DDOTPU,
-  TILEGX_OPC_V1DDOTPUA,
-  TILEGX_OPC_V1DDOTPUS,
-  TILEGX_OPC_V1DDOTPUSA,
-  TILEGX_OPC_V1DOTP,
-  TILEGX_OPC_V1DOTPA,
-  TILEGX_OPC_V1DOTPU,
-  TILEGX_OPC_V1DOTPUA,
-  TILEGX_OPC_V1DOTPUS,
-  TILEGX_OPC_V1DOTPUSA,
-  TILEGX_OPC_V1INT_H,
-  TILEGX_OPC_V1INT_L,
-  TILEGX_OPC_V1MAXU,
-  TILEGX_OPC_V1MAXUI,
-  TILEGX_OPC_V1MINU,
-  TILEGX_OPC_V1MINUI,
-  TILEGX_OPC_V1MNZ,
-  TILEGX_OPC_V1MULTU,
-  TILEGX_OPC_V1MULU,
-  TILEGX_OPC_V1MULUS,
-  TILEGX_OPC_V1MZ,
-  TILEGX_OPC_V1SADAU,
-  TILEGX_OPC_V1SADU,
-  TILEGX_OPC_V1SHL,
-  TILEGX_OPC_V1SHLI,
-  TILEGX_OPC_V1SHRS,
-  TILEGX_OPC_V1SHRSI,
-  TILEGX_OPC_V1SHRU,
-  TILEGX_OPC_V1SHRUI,
-  TILEGX_OPC_V1SUB,
-  TILEGX_OPC_V1SUBUC,
-  TILEGX_OPC_V2ADD,
-  TILEGX_OPC_V2ADDI,
-  TILEGX_OPC_V2ADDSC,
-  TILEGX_OPC_V2ADIFFS,
-  TILEGX_OPC_V2AVGS,
-  TILEGX_OPC_V2CMPEQ,
-  TILEGX_OPC_V2CMPEQI,
-  TILEGX_OPC_V2CMPLES,
-  TILEGX_OPC_V2CMPLEU,
-  TILEGX_OPC_V2CMPLTS,
-  TILEGX_OPC_V2CMPLTSI,
-  TILEGX_OPC_V2CMPLTU,
-  TILEGX_OPC_V2CMPLTUI,
-  TILEGX_OPC_V2CMPNE,
-  TILEGX_OPC_V2DOTP,
-  TILEGX_OPC_V2DOTPA,
-  TILEGX_OPC_V2INT_H,
-  TILEGX_OPC_V2INT_L,
-  TILEGX_OPC_V2MAXS,
-  TILEGX_OPC_V2MAXSI,
-  TILEGX_OPC_V2MINS,
-  TILEGX_OPC_V2MINSI,
-  TILEGX_OPC_V2MNZ,
-  TILEGX_OPC_V2MULFSC,
-  TILEGX_OPC_V2MULS,
-  TILEGX_OPC_V2MULTS,
-  TILEGX_OPC_V2MZ,
-  TILEGX_OPC_V2PACKH,
-  TILEGX_OPC_V2PACKL,
-  TILEGX_OPC_V2PACKUC,
-  TILEGX_OPC_V2SADAS,
-  TILEGX_OPC_V2SADAU,
-  TILEGX_OPC_V2SADS,
-  TILEGX_OPC_V2SADU,
-  TILEGX_OPC_V2SHL,
-  TILEGX_OPC_V2SHLI,
-  TILEGX_OPC_V2SHLSC,
-  TILEGX_OPC_V2SHRS,
-  TILEGX_OPC_V2SHRSI,
-  TILEGX_OPC_V2SHRU,
-  TILEGX_OPC_V2SHRUI,
-  TILEGX_OPC_V2SUB,
-  TILEGX_OPC_V2SUBSC,
-  TILEGX_OPC_V4ADD,
-  TILEGX_OPC_V4ADDSC,
-  TILEGX_OPC_V4INT_H,
-  TILEGX_OPC_V4INT_L,
-  TILEGX_OPC_V4PACKSC,
-  TILEGX_OPC_V4SHL,
-  TILEGX_OPC_V4SHLSC,
-  TILEGX_OPC_V4SHRS,
-  TILEGX_OPC_V4SHRU,
-  TILEGX_OPC_V4SUB,
-  TILEGX_OPC_V4SUBSC,
-  TILEGX_OPC_WH64,
-  TILEGX_OPC_XOR,
-  TILEGX_OPC_XORI,
-  TILEGX_OPC_NONE
-} tilegx_mnemonic;
-
-/* 64-bit pattern for a { bpt ; nop } bundle. */
-#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
-
-
-#define TILE_ELF_MACHINE_CODE EM_TILE64
-
-#define TILE_ELF_NAME "elf32-tile64"
-
-
-static __inline unsigned int
-get_BFEnd_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 24)) & 0xf);
-}
-
-static __inline unsigned int
-get_BFStart_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x3f);
-}
-
-static __inline unsigned int
-get_BrOff_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x0000003f) |
-         (((unsigned int)(n >> 37)) & 0x0001ffc0);
-}
-
-static __inline unsigned int
-get_BrType_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 54)) & 0x1f);
-}
-
-static __inline unsigned int
-get_Dest_Imm8_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x0000003f) |
-         (((unsigned int)(n >> 43)) & 0x000000c0);
-}
-
-static __inline unsigned int
-get_Dest_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_Y0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_Y1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Imm16_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0xffff);
-}
-
-static __inline unsigned int
-get_Imm16_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0xffff);
-}
-
-static __inline unsigned int
-get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 20)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 51)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_Y0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_Y1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0xff);
-}
-
-static __inline unsigned int
-get_JumpOff_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x7ffffff);
-}
-
-static __inline unsigned int
-get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 58)) & 0x1);
-}
-
-static __inline unsigned int
-get_MF_Imm14_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 37)) & 0x3fff);
-}
-
-static __inline unsigned int
-get_MT_Imm14_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 31)) & 0x0000003f) |
-         (((unsigned int)(n >> 37)) & 0x00003fc0);
-}
-
-static __inline unsigned int
-get_Mode(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 62)) & 0x3);
-}
-
-static __inline unsigned int
-get_Opcode_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 28)) & 0x7);
-}
-
-static __inline unsigned int
-get_Opcode_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 59)) & 0x7);
-}
-
-static __inline unsigned int
-get_Opcode_Y0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 27)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 58)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y2(tilegx_bundle_bits n)
-{
-  return (((n >> 26)) & 0x00000001) |
-         (((unsigned int)(n >> 56)) & 0x00000002);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 49)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_Y0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x3);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_Y1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 49)) & 0x3);
-}
-
-static __inline unsigned int
-get_ShAmt_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShAmt_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShAmt_Y0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShAmt_Y1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 49)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x3);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 49)) & 0x3);
-}
-
-static __inline unsigned int
-get_SrcA_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 6)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 37)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 6)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 37)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y2(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 20)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcBDest_Y2(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 51)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_Y0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_Y1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-
-static __inline int
-sign_extend(int n, int num_bits)
-{
-  int shift = (int)(sizeof(int) * 8 - num_bits);
-  return (n << shift) >> shift;
-}
-
-
-
-static __inline tilegx_bundle_bits
-create_BFEnd_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_BFOpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xf) << 24);
-}
-
-static __inline tilegx_bundle_bits
-create_BFStart_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_BrOff_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
-         (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_BrType_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x1f)) << 54);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_Imm8_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
-         (((tilegx_bundle_bits)(n & 0x000000c0)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 0);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 0);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm16_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xffff) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm16_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0xffff)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8OpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xff) << 20);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8OpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0xff)) << 51);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xff) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0xff)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xff) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0xff)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_JumpOff_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31);
-}
-
-static __inline tilegx_bundle_bits
-create_JumpOpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x1)) << 58);
-}
-
-static __inline tilegx_bundle_bits
-create_MF_Imm14_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3fff)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_MT_Imm14_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
-         (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_Mode(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3)) << 62);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x7) << 28);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x7)) << 59);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xf) << 27);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0xf)) << 58);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_Y2(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x00000001) << 26) |
-         (((tilegx_bundle_bits)(n & 0x00000002)) << 56);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3ff) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3ff) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 6);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 6);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_Y2(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 20);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcBDest_Y2(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 51);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-
-typedef enum
-{
-  TILEGX_PIPELINE_X0,
-  TILEGX_PIPELINE_X1,
-  TILEGX_PIPELINE_Y0,
-  TILEGX_PIPELINE_Y1,
-  TILEGX_PIPELINE_Y2,
-} tilegx_pipeline;
-
-#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)
-
-typedef enum
-{
-  TILEGX_OP_TYPE_REGISTER,
-  TILEGX_OP_TYPE_IMMEDIATE,
-  TILEGX_OP_TYPE_ADDRESS,
-  TILEGX_OP_TYPE_SPR
-} tilegx_operand_type;
-
-/* These are the bits that determine if a bundle is in the X encoding. */
-#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
-
-enum
-{
-  /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
-  TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
-
-  /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
-  TILEGX_NUM_PIPELINE_ENCODINGS = 5,
-
-  /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */
-  TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
-
-  /* Instructions take this many bytes. */
-  TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,
-
-  /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */
-  TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
-
-  /* Bundles should be aligned modulo this number of bytes. */
-  TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =
-    (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
-
-  /* Number of registers (some are magic, such as network I/O). */
-  TILEGX_NUM_REGISTERS = 64,
-};
-
-
-struct tilegx_operand
-{
-  /* Is this operand a register, immediate or address? */
-  tilegx_operand_type type;
-
-  /* The default relocation type for this operand.  */
-  signed int default_reloc : 16;
-
-  /* How many bits is this value? (used for range checking) */
-  unsigned int num_bits : 5;
-
-  /* Is the value signed? (used for range checking) */
-  unsigned int is_signed : 1;
-
-  /* Is this operand a source register? */
-  unsigned int is_src_reg : 1;
-
-  /* Is this operand written? (i.e. is it a destination register) */
-  unsigned int is_dest_reg : 1;
-
-  /* Is this operand PC-relative? */
-  unsigned int is_pc_relative : 1;
-
-  /* By how many bits do we right shift the value before inserting? */
-  unsigned int rightshift : 2;
-
-  /* Return the bits for this operand to be ORed into an existing bundle. */
-  tilegx_bundle_bits (*insert) (int op);
-
-  /* Extract this operand and return it. */
-  unsigned int (*extract) (tilegx_bundle_bits bundle);
-};
-
-
-extern const struct tilegx_operand tilegx_operands[];
-
-/* One finite-state machine per pipe for rapid instruction decoding. */
-extern const unsigned short * const
-tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS];
-
-
-struct tilegx_opcode
-{
-  /* The opcode mnemonic, e.g. "add" */
-  const char *name;
-
-  /* The enum value for this mnemonic. */
-  tilegx_mnemonic mnemonic;
-
-  /* A bit mask of which of the five pipes this instruction
-     is compatible with:
-     X0  0x01
-     X1  0x02
-     Y0  0x04
-     Y1  0x08
-     Y2  0x10 */
-  unsigned char pipes;
-
-  /* How many operands are there? */
-  unsigned char num_operands;
-
-  /* Which register does this write implicitly, or TREG_ZERO if none? */
-  unsigned char implicitly_written_register;
-
-  /* Can this be bundled with other instructions (almost always true). */
-  unsigned char can_bundle;
-
-  /* The description of the operands. Each of these is an
-   * index into the tilegx_operands[] table. */
-  unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS];
-
-};
-
-extern const struct tilegx_opcode tilegx_opcodes[];
-
-/* Used for non-textual disassembly into structs. */
-struct tilegx_decoded_instruction
-{
-  const struct tilegx_opcode *opcode;
-  const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS];
-  long long operand_values[TILEGX_MAX_OPERANDS];
-};
-
-
-/* Disassemble a bundle into a struct for machine processing. */
-extern int parse_insn_tilegx(tilegx_bundle_bits bits,
-                             unsigned long long pc,
-                             struct tilegx_decoded_instruction
-                             decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]);
-
-
-
-#endif /* opcode_tilegx_h */
diff --git a/arch/tile/include/asm/opcode_constants_32.h b/arch/tile/include/asm/opcode_constants_32.h
deleted file mode 100644 (file)
index 227d033..0000000
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation, version 2.
- *
- *   This program is distributed in the hope that it will be useful, but
- *   WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- *   NON INFRINGEMENT.  See the GNU General Public License for
- *   more details.
- */
-
-/* This file is machine-generated; DO NOT EDIT! */
-
-
-#ifndef _TILE_OPCODE_CONSTANTS_H
-#define _TILE_OPCODE_CONSTANTS_H
-enum
-{
-  ADDBS_U_SPECIAL_0_OPCODE_X0 = 98,
-  ADDBS_U_SPECIAL_0_OPCODE_X1 = 68,
-  ADDB_SPECIAL_0_OPCODE_X0 = 1,
-  ADDB_SPECIAL_0_OPCODE_X1 = 1,
-  ADDHS_SPECIAL_0_OPCODE_X0 = 99,
-  ADDHS_SPECIAL_0_OPCODE_X1 = 69,
-  ADDH_SPECIAL_0_OPCODE_X0 = 2,
-  ADDH_SPECIAL_0_OPCODE_X1 = 2,
-  ADDIB_IMM_0_OPCODE_X0 = 1,
-  ADDIB_IMM_0_OPCODE_X1 = 1,
-  ADDIH_IMM_0_OPCODE_X0 = 2,
-  ADDIH_IMM_0_OPCODE_X1 = 2,
-  ADDI_IMM_0_OPCODE_X0 = 3,
-  ADDI_IMM_0_OPCODE_X1 = 3,
-  ADDI_IMM_1_OPCODE_SN = 1,
-  ADDI_OPCODE_Y0 = 9,
-  ADDI_OPCODE_Y1 = 7,
-  ADDLIS_OPCODE_X0 = 1,
-  ADDLIS_OPCODE_X1 = 2,
-  ADDLI_OPCODE_X0 = 2,
-  ADDLI_OPCODE_X1 = 3,
-  ADDS_SPECIAL_0_OPCODE_X0 = 96,
-  ADDS_SPECIAL_0_OPCODE_X1 = 66,
-  ADD_SPECIAL_0_OPCODE_X0 = 3,
-  ADD_SPECIAL_0_OPCODE_X1 = 3,
-  ADD_SPECIAL_0_OPCODE_Y0 = 0,
-  ADD_SPECIAL_0_OPCODE_Y1 = 0,
-  ADIFFB_U_SPECIAL_0_OPCODE_X0 = 4,
-  ADIFFH_SPECIAL_0_OPCODE_X0 = 5,
-  ANDI_IMM_0_OPCODE_X0 = 1,
-  ANDI_IMM_0_OPCODE_X1 = 4,
-  ANDI_OPCODE_Y0 = 10,
-  ANDI_OPCODE_Y1 = 8,
-  AND_SPECIAL_0_OPCODE_X0 = 6,
-  AND_SPECIAL_0_OPCODE_X1 = 4,
-  AND_SPECIAL_2_OPCODE_Y0 = 0,
-  AND_SPECIAL_2_OPCODE_Y1 = 0,
-  AULI_OPCODE_X0 = 3,
-  AULI_OPCODE_X1 = 4,
-  AVGB_U_SPECIAL_0_OPCODE_X0 = 7,
-  AVGH_SPECIAL_0_OPCODE_X0 = 8,
-  BBNST_BRANCH_OPCODE_X1 = 15,
-  BBNS_BRANCH_OPCODE_X1 = 14,
-  BBNS_OPCODE_SN = 63,
-  BBST_BRANCH_OPCODE_X1 = 13,
-  BBS_BRANCH_OPCODE_X1 = 12,
-  BBS_OPCODE_SN = 62,
-  BGEZT_BRANCH_OPCODE_X1 = 7,
-  BGEZ_BRANCH_OPCODE_X1 = 6,
-  BGEZ_OPCODE_SN = 61,
-  BGZT_BRANCH_OPCODE_X1 = 5,
-  BGZ_BRANCH_OPCODE_X1 = 4,
-  BGZ_OPCODE_SN = 58,
-  BITX_UN_0_SHUN_0_OPCODE_X0 = 1,
-  BITX_UN_0_SHUN_0_OPCODE_Y0 = 1,
-  BLEZT_BRANCH_OPCODE_X1 = 11,
-  BLEZ_BRANCH_OPCODE_X1 = 10,
-  BLEZ_OPCODE_SN = 59,
-  BLZT_BRANCH_OPCODE_X1 = 9,
-  BLZ_BRANCH_OPCODE_X1 = 8,
-  BLZ_OPCODE_SN = 60,
-  BNZT_BRANCH_OPCODE_X1 = 3,
-  BNZ_BRANCH_OPCODE_X1 = 2,
-  BNZ_OPCODE_SN = 57,
-  BPT_NOREG_RR_IMM_0_OPCODE_SN = 1,
-  BRANCH_OPCODE_X1 = 5,
-  BYTEX_UN_0_SHUN_0_OPCODE_X0 = 2,
-  BYTEX_UN_0_SHUN_0_OPCODE_Y0 = 2,
-  BZT_BRANCH_OPCODE_X1 = 1,
-  BZ_BRANCH_OPCODE_X1 = 0,
-  BZ_OPCODE_SN = 56,
-  CLZ_UN_0_SHUN_0_OPCODE_X0 = 3,
-  CLZ_UN_0_SHUN_0_OPCODE_Y0 = 3,
-  CRC32_32_SPECIAL_0_OPCODE_X0 = 9,
-  CRC32_8_SPECIAL_0_OPCODE_X0 = 10,
-  CTZ_UN_0_SHUN_0_OPCODE_X0 = 4,
-  CTZ_UN_0_SHUN_0_OPCODE_Y0 = 4,
-  DRAIN_UN_0_SHUN_0_OPCODE_X1 = 1,
-  DTLBPR_UN_0_SHUN_0_OPCODE_X1 = 2,
-  DWORD_ALIGN_SPECIAL_0_OPCODE_X0 = 95,
-  FINV_UN_0_SHUN_0_OPCODE_X1 = 3,
-  FLUSH_UN_0_SHUN_0_OPCODE_X1 = 4,
-  FNOP_NOREG_RR_IMM_0_OPCODE_SN = 3,
-  FNOP_UN_0_SHUN_0_OPCODE_X0 = 5,
-  FNOP_UN_0_SHUN_0_OPCODE_X1 = 5,
-  FNOP_UN_0_SHUN_0_OPCODE_Y0 = 5,
-  FNOP_UN_0_SHUN_0_OPCODE_Y1 = 1,
-  HALT_NOREG_RR_IMM_0_OPCODE_SN = 0,
-  ICOH_UN_0_SHUN_0_OPCODE_X1 = 6,
-  ILL_UN_0_SHUN_0_OPCODE_X1 = 7,
-  ILL_UN_0_SHUN_0_OPCODE_Y1 = 2,
-  IMM_0_OPCODE_SN = 0,
-  IMM_0_OPCODE_X0 = 4,
-  IMM_0_OPCODE_X1 = 6,
-  IMM_1_OPCODE_SN = 1,
-  IMM_OPCODE_0_X0 = 5,
-  INTHB_SPECIAL_0_OPCODE_X0 = 11,
-  INTHB_SPECIAL_0_OPCODE_X1 = 5,
-  INTHH_SPECIAL_0_OPCODE_X0 = 12,
-  INTHH_SPECIAL_0_OPCODE_X1 = 6,
-  INTLB_SPECIAL_0_OPCODE_X0 = 13,
-  INTLB_SPECIAL_0_OPCODE_X1 = 7,
-  INTLH_SPECIAL_0_OPCODE_X0 = 14,
-  INTLH_SPECIAL_0_OPCODE_X1 = 8,
-  INV_UN_0_SHUN_0_OPCODE_X1 = 8,
-  IRET_UN_0_SHUN_0_OPCODE_X1 = 9,
-  JALB_OPCODE_X1 = 13,
-  JALF_OPCODE_X1 = 12,
-  JALRP_SPECIAL_0_OPCODE_X1 = 9,
-  JALRR_IMM_1_OPCODE_SN = 3,
-  JALR_RR_IMM_0_OPCODE_SN = 5,
-  JALR_SPECIAL_0_OPCODE_X1 = 10,
-  JB_OPCODE_X1 = 11,
-  JF_OPCODE_X1 = 10,
-  JRP_SPECIAL_0_OPCODE_X1 = 11,
-  JRR_IMM_1_OPCODE_SN = 2,
-  JR_RR_IMM_0_OPCODE_SN = 4,
-  JR_SPECIAL_0_OPCODE_X1 = 12,
-  LBADD_IMM_0_OPCODE_X1 = 22,
-  LBADD_U_IMM_0_OPCODE_X1 = 23,
-  LB_OPCODE_Y2 = 0,
-  LB_UN_0_SHUN_0_OPCODE_X1 = 10,
-  LB_U_OPCODE_Y2 = 1,
-  LB_U_UN_0_SHUN_0_OPCODE_X1 = 11,
-  LHADD_IMM_0_OPCODE_X1 = 24,
-  LHADD_U_IMM_0_OPCODE_X1 = 25,
-  LH_OPCODE_Y2 = 2,
-  LH_UN_0_SHUN_0_OPCODE_X1 = 12,
-  LH_U_OPCODE_Y2 = 3,
-  LH_U_UN_0_SHUN_0_OPCODE_X1 = 13,
-  LNK_SPECIAL_0_OPCODE_X1 = 13,
-  LWADD_IMM_0_OPCODE_X1 = 26,
-  LWADD_NA_IMM_0_OPCODE_X1 = 27,
-  LW_NA_UN_0_SHUN_0_OPCODE_X1 = 24,
-  LW_OPCODE_Y2 = 4,
-  LW_UN_0_SHUN_0_OPCODE_X1 = 14,
-  MAXB_U_SPECIAL_0_OPCODE_X0 = 15,
-  MAXB_U_SPECIAL_0_OPCODE_X1 = 14,
-  MAXH_SPECIAL_0_OPCODE_X0 = 16,
-  MAXH_SPECIAL_0_OPCODE_X1 = 15,
-  MAXIB_U_IMM_0_OPCODE_X0 = 4,
-  MAXIB_U_IMM_0_OPCODE_X1 = 5,
-  MAXIH_IMM_0_OPCODE_X0 = 5,
-  MAXIH_IMM_0_OPCODE_X1 = 6,
-  MFSPR_IMM_0_OPCODE_X1 = 7,
-  MF_UN_0_SHUN_0_OPCODE_X1 = 15,
-  MINB_U_SPECIAL_0_OPCODE_X0 = 17,
-  MINB_U_SPECIAL_0_OPCODE_X1 = 16,
-  MINH_SPECIAL_0_OPCODE_X0 = 18,
-  MINH_SPECIAL_0_OPCODE_X1 = 17,
-  MINIB_U_IMM_0_OPCODE_X0 = 6,
-  MINIB_U_IMM_0_OPCODE_X1 = 8,
-  MINIH_IMM_0_OPCODE_X0 = 7,
-  MINIH_IMM_0_OPCODE_X1 = 9,
-  MM_OPCODE_X0 = 6,
-  MM_OPCODE_X1 = 7,
-  MNZB_SPECIAL_0_OPCODE_X0 = 19,
-  MNZB_SPECIAL_0_OPCODE_X1 = 18,
-  MNZH_SPECIAL_0_OPCODE_X0 = 20,
-  MNZH_SPECIAL_0_OPCODE_X1 = 19,
-  MNZ_SPECIAL_0_OPCODE_X0 = 21,
-  MNZ_SPECIAL_0_OPCODE_X1 = 20,
-  MNZ_SPECIAL_1_OPCODE_Y0 = 0,
-  MNZ_SPECIAL_1_OPCODE_Y1 = 1,
-  MOVEI_IMM_1_OPCODE_SN = 0,
-  MOVE_RR_IMM_0_OPCODE_SN = 8,
-  MTSPR_IMM_0_OPCODE_X1 = 10,
-  MULHHA_SS_SPECIAL_0_OPCODE_X0 = 22,
-  MULHHA_SS_SPECIAL_7_OPCODE_Y0 = 0,
-  MULHHA_SU_SPECIAL_0_OPCODE_X0 = 23,
-  MULHHA_UU_SPECIAL_0_OPCODE_X0 = 24,
-  MULHHA_UU_SPECIAL_7_OPCODE_Y0 = 1,
-  MULHHSA_UU_SPECIAL_0_OPCODE_X0 = 25,
-  MULHH_SS_SPECIAL_0_OPCODE_X0 = 26,
-  MULHH_SS_SPECIAL_6_OPCODE_Y0 = 0,
-  MULHH_SU_SPECIAL_0_OPCODE_X0 = 27,
-  MULHH_UU_SPECIAL_0_OPCODE_X0 = 28,
-  MULHH_UU_SPECIAL_6_OPCODE_Y0 = 1,
-  MULHLA_SS_SPECIAL_0_OPCODE_X0 = 29,
-  MULHLA_SU_SPECIAL_0_OPCODE_X0 = 30,
-  MULHLA_US_SPECIAL_0_OPCODE_X0 = 31,
-  MULHLA_UU_SPECIAL_0_OPCODE_X0 = 32,
-  MULHLSA_UU_SPECIAL_0_OPCODE_X0 = 33,
-  MULHLSA_UU_SPECIAL_5_OPCODE_Y0 = 0,
-  MULHL_SS_SPECIAL_0_OPCODE_X0 = 34,
-  MULHL_SU_SPECIAL_0_OPCODE_X0 = 35,
-  MULHL_US_SPECIAL_0_OPCODE_X0 = 36,
-  MULHL_UU_SPECIAL_0_OPCODE_X0 = 37,
-  MULLLA_SS_SPECIAL_0_OPCODE_X0 = 38,
-  MULLLA_SS_SPECIAL_7_OPCODE_Y0 = 2,
-  MULLLA_SU_SPECIAL_0_OPCODE_X0 = 39,
-  MULLLA_UU_SPECIAL_0_OPCODE_X0 = 40,
-  MULLLA_UU_SPECIAL_7_OPCODE_Y0 = 3,
-  MULLLSA_UU_SPECIAL_0_OPCODE_X0 = 41,
-  MULLL_SS_SPECIAL_0_OPCODE_X0 = 42,
-  MULLL_SS_SPECIAL_6_OPCODE_Y0 = 2,
-  MULLL_SU_SPECIAL_0_OPCODE_X0 = 43,
-  MULLL_UU_SPECIAL_0_OPCODE_X0 = 44,
-  MULLL_UU_SPECIAL_6_OPCODE_Y0 = 3,
-  MVNZ_SPECIAL_0_OPCODE_X0 = 45,
-  MVNZ_SPECIAL_1_OPCODE_Y0 = 1,
-  MVZ_SPECIAL_0_OPCODE_X0 = 46,
-  MVZ_SPECIAL_1_OPCODE_Y0 = 2,
-  MZB_SPECIAL_0_OPCODE_X0 = 47,
-  MZB_SPECIAL_0_OPCODE_X1 = 21,
-  MZH_SPECIAL_0_OPCODE_X0 = 48,
-  MZH_SPECIAL_0_OPCODE_X1 = 22,
-  MZ_SPECIAL_0_OPCODE_X0 = 49,
-  MZ_SPECIAL_0_OPCODE_X1 = 23,
-  MZ_SPECIAL_1_OPCODE_Y0 = 3,
-  MZ_SPECIAL_1_OPCODE_Y1 = 2,
-  NAP_UN_0_SHUN_0_OPCODE_X1 = 16,
-  NOP_NOREG_RR_IMM_0_OPCODE_SN = 2,
-  NOP_UN_0_SHUN_0_OPCODE_X0 = 6,
-  NOP_UN_0_SHUN_0_OPCODE_X1 = 17,
-  NOP_UN_0_SHUN_0_OPCODE_Y0 = 6,
-  NOP_UN_0_SHUN_0_OPCODE_Y1 = 3,
-  NOREG_RR_IMM_0_OPCODE_SN = 0,
-  NOR_SPECIAL_0_OPCODE_X0 = 50,
-  NOR_SPECIAL_0_OPCODE_X1 = 24,
-  NOR_SPECIAL_2_OPCODE_Y0 = 1,
-  NOR_SPECIAL_2_OPCODE_Y1 = 1,
-  ORI_IMM_0_OPCODE_X0 = 8,
-  ORI_IMM_0_OPCODE_X1 = 11,
-  ORI_OPCODE_Y0 = 11,
-  ORI_OPCODE_Y1 = 9,
-  OR_SPECIAL_0_OPCODE_X0 = 51,
-  OR_SPECIAL_0_OPCODE_X1 = 25,
-  OR_SPECIAL_2_OPCODE_Y0 = 2,
-  OR_SPECIAL_2_OPCODE_Y1 = 2,
-  PACKBS_U_SPECIAL_0_OPCODE_X0 = 103,
-  PACKBS_U_SPECIAL_0_OPCODE_X1 = 73,
-  PACKHB_SPECIAL_0_OPCODE_X0 = 52,
-  PACKHB_SPECIAL_0_OPCODE_X1 = 26,
-  PACKHS_SPECIAL_0_OPCODE_X0 = 102,
-  PACKHS_SPECIAL_0_OPCODE_X1 = 72,
-  PACKLB_SPECIAL_0_OPCODE_X0 = 53,
-  PACKLB_SPECIAL_0_OPCODE_X1 = 27,
-  PCNT_UN_0_SHUN_0_OPCODE_X0 = 7,
-  PCNT_UN_0_SHUN_0_OPCODE_Y0 = 7,
-  RLI_SHUN_0_OPCODE_X0 = 1,
-  RLI_SHUN_0_OPCODE_X1 = 1,
-  RLI_SHUN_0_OPCODE_Y0 = 1,
-  RLI_SHUN_0_OPCODE_Y1 = 1,
-  RL_SPECIAL_0_OPCODE_X0 = 54,
-  RL_SPECIAL_0_OPCODE_X1 = 28,
-  RL_SPECIAL_3_OPCODE_Y0 = 0,
-  RL_SPECIAL_3_OPCODE_Y1 = 0,
-  RR_IMM_0_OPCODE_SN = 0,
-  S1A_SPECIAL_0_OPCODE_X0 = 55,
-  S1A_SPECIAL_0_OPCODE_X1 = 29,
-  S1A_SPECIAL_0_OPCODE_Y0 = 1,
-  S1A_SPECIAL_0_OPCODE_Y1 = 1,
-  S2A_SPECIAL_0_OPCODE_X0 = 56,
-  S2A_SPECIAL_0_OPCODE_X1 = 30,
-  S2A_SPECIAL_0_OPCODE_Y0 = 2,
-  S2A_SPECIAL_0_OPCODE_Y1 = 2,
-  S3A_SPECIAL_0_OPCODE_X0 = 57,
-  S3A_SPECIAL_0_OPCODE_X1 = 31,
-  S3A_SPECIAL_5_OPCODE_Y0 = 1,
-  S3A_SPECIAL_5_OPCODE_Y1 = 1,
-  SADAB_U_SPECIAL_0_OPCODE_X0 = 58,
-  SADAH_SPECIAL_0_OPCODE_X0 = 59,
-  SADAH_U_SPECIAL_0_OPCODE_X0 = 60,
-  SADB_U_SPECIAL_0_OPCODE_X0 = 61,
-  SADH_SPECIAL_0_OPCODE_X0 = 62,
-  SADH_U_SPECIAL_0_OPCODE_X0 = 63,
-  SBADD_IMM_0_OPCODE_X1 = 28,
-  SB_OPCODE_Y2 = 5,
-  SB_SPECIAL_0_OPCODE_X1 = 32,
-  SEQB_SPECIAL_0_OPCODE_X0 = 64,
-  SEQB_SPECIAL_0_OPCODE_X1 = 33,
-  SEQH_SPECIAL_0_OPCODE_X0 = 65,
-  SEQH_SPECIAL_0_OPCODE_X1 = 34,
-  SEQIB_IMM_0_OPCODE_X0 = 9,
-  SEQIB_IMM_0_OPCODE_X1 = 12,
-  SEQIH_IMM_0_OPCODE_X0 = 10,
-  SEQIH_IMM_0_OPCODE_X1 = 13,
-  SEQI_IMM_0_OPCODE_X0 = 11,
-  SEQI_IMM_0_OPCODE_X1 = 14,
-  SEQI_OPCODE_Y0 = 12,
-  SEQI_OPCODE_Y1 = 10,
-  SEQ_SPECIAL_0_OPCODE_X0 = 66,
-  SEQ_SPECIAL_0_OPCODE_X1 = 35,
-  SEQ_SPECIAL_5_OPCODE_Y0 = 2,
-  SEQ_SPECIAL_5_OPCODE_Y1 = 2,
-  SHADD_IMM_0_OPCODE_X1 = 29,
-  SHL8II_IMM_0_OPCODE_SN = 3,
-  SHLB_SPECIAL_0_OPCODE_X0 = 67,
-  SHLB_SPECIAL_0_OPCODE_X1 = 36,
-  SHLH_SPECIAL_0_OPCODE_X0 = 68,
-  SHLH_SPECIAL_0_OPCODE_X1 = 37,
-  SHLIB_SHUN_0_OPCODE_X0 = 2,
-  SHLIB_SHUN_0_OPCODE_X1 = 2,
-  SHLIH_SHUN_0_OPCODE_X0 = 3,
-  SHLIH_SHUN_0_OPCODE_X1 = 3,
-  SHLI_SHUN_0_OPCODE_X0 = 4,
-  SHLI_SHUN_0_OPCODE_X1 = 4,
-  SHLI_SHUN_0_OPCODE_Y0 = 2,
-  SHLI_SHUN_0_OPCODE_Y1 = 2,
-  SHL_SPECIAL_0_OPCODE_X0 = 69,
-  SHL_SPECIAL_0_OPCODE_X1 = 38,
-  SHL_SPECIAL_3_OPCODE_Y0 = 1,
-  SHL_SPECIAL_3_OPCODE_Y1 = 1,
-  SHR1_RR_IMM_0_OPCODE_SN = 9,
-  SHRB_SPECIAL_0_OPCODE_X0 = 70,
-  SHRB_SPECIAL_0_OPCODE_X1 = 39,
-  SHRH_SPECIAL_0_OPCODE_X0 = 71,
-  SHRH_SPECIAL_0_OPCODE_X1 = 40,
-  SHRIB_SHUN_0_OPCODE_X0 = 5,
-  SHRIB_SHUN_0_OPCODE_X1 = 5,
-  SHRIH_SHUN_0_OPCODE_X0 = 6,
-  SHRIH_SHUN_0_OPCODE_X1 = 6,
-  SHRI_SHUN_0_OPCODE_X0 = 7,
-  SHRI_SHUN_0_OPCODE_X1 = 7,
-  SHRI_SHUN_0_OPCODE_Y0 = 3,
-  SHRI_SHUN_0_OPCODE_Y1 = 3,
-  SHR_SPECIAL_0_OPCODE_X0 = 72,
-  SHR_SPECIAL_0_OPCODE_X1 = 41,
-  SHR_SPECIAL_3_OPCODE_Y0 = 2,
-  SHR_SPECIAL_3_OPCODE_Y1 = 2,
-  SHUN_0_OPCODE_X0 = 7,
-  SHUN_0_OPCODE_X1 = 8,
-  SHUN_0_OPCODE_Y0 = 13,
-  SHUN_0_OPCODE_Y1 = 11,
-  SH_OPCODE_Y2 = 6,
-  SH_SPECIAL_0_OPCODE_X1 = 42,
-  SLTB_SPECIAL_0_OPCODE_X0 = 73,
-  SLTB_SPECIAL_0_OPCODE_X1 = 43,
-  SLTB_U_SPECIAL_0_OPCODE_X0 = 74,
-  SLTB_U_SPECIAL_0_OPCODE_X1 = 44,
-  SLTEB_SPECIAL_0_OPCODE_X0 = 75,
-  SLTEB_SPECIAL_0_OPCODE_X1 = 45,
-  SLTEB_U_SPECIAL_0_OPCODE_X0 = 76,
-  SLTEB_U_SPECIAL_0_OPCODE_X1 = 46,
-  SLTEH_SPECIAL_0_OPCODE_X0 = 77,
-  SLTEH_SPECIAL_0_OPCODE_X1 = 47,
-  SLTEH_U_SPECIAL_0_OPCODE_X0 = 78,
-  SLTEH_U_SPECIAL_0_OPCODE_X1 = 48,
-  SLTE_SPECIAL_0_OPCODE_X0 = 79,
-  SLTE_SPECIAL_0_OPCODE_X1 = 49,
-  SLTE_SPECIAL_4_OPCODE_Y0 = 0,
-  SLTE_SPECIAL_4_OPCODE_Y1 = 0,
-  SLTE_U_SPECIAL_0_OPCODE_X0 = 80,
-  SLTE_U_SPECIAL_0_OPCODE_X1 = 50,
-  SLTE_U_SPECIAL_4_OPCODE_Y0 = 1,
-  SLTE_U_SPECIAL_4_OPCODE_Y1 = 1,
-  SLTH_SPECIAL_0_OPCODE_X0 = 81,
-  SLTH_SPECIAL_0_OPCODE_X1 = 51,
-  SLTH_U_SPECIAL_0_OPCODE_X0 = 82,
-  SLTH_U_SPECIAL_0_OPCODE_X1 = 52,
-  SLTIB_IMM_0_OPCODE_X0 = 12,
-  SLTIB_IMM_0_OPCODE_X1 = 15,
-  SLTIB_U_IMM_0_OPCODE_X0 = 13,
-  SLTIB_U_IMM_0_OPCODE_X1 = 16,
-  SLTIH_IMM_0_OPCODE_X0 = 14,
-  SLTIH_IMM_0_OPCODE_X1 = 17,
-  SLTIH_U_IMM_0_OPCODE_X0 = 15,
-  SLTIH_U_IMM_0_OPCODE_X1 = 18,
-  SLTI_IMM_0_OPCODE_X0 = 16,
-  SLTI_IMM_0_OPCODE_X1 = 19,
-  SLTI_OPCODE_Y0 = 14,
-  SLTI_OPCODE_Y1 = 12,
-  SLTI_U_IMM_0_OPCODE_X0 = 17,
-  SLTI_U_IMM_0_OPCODE_X1 = 20,
-  SLTI_U_OPCODE_Y0 = 15,
-  SLTI_U_OPCODE_Y1 = 13,
-  SLT_SPECIAL_0_OPCODE_X0 = 83,
-  SLT_SPECIAL_0_OPCODE_X1 = 53,
-  SLT_SPECIAL_4_OPCODE_Y0 = 2,
-  SLT_SPECIAL_4_OPCODE_Y1 = 2,
-  SLT_U_SPECIAL_0_OPCODE_X0 = 84,
-  SLT_U_SPECIAL_0_OPCODE_X1 = 54,
-  SLT_U_SPECIAL_4_OPCODE_Y0 = 3,
-  SLT_U_SPECIAL_4_OPCODE_Y1 = 3,
-  SNEB_SPECIAL_0_OPCODE_X0 = 85,
-  SNEB_SPECIAL_0_OPCODE_X1 = 55,
-  SNEH_SPECIAL_0_OPCODE_X0 = 86,
-  SNEH_SPECIAL_0_OPCODE_X1 = 56,
-  SNE_SPECIAL_0_OPCODE_X0 = 87,
-  SNE_SPECIAL_0_OPCODE_X1 = 57,
-  SNE_SPECIAL_5_OPCODE_Y0 = 3,
-  SNE_SPECIAL_5_OPCODE_Y1 = 3,
-  SPECIAL_0_OPCODE_X0 = 0,
-  SPECIAL_0_OPCODE_X1 = 1,
-  SPECIAL_0_OPCODE_Y0 = 1,
-  SPECIAL_0_OPCODE_Y1 = 1,
-  SPECIAL_1_OPCODE_Y0 = 2,
-  SPECIAL_1_OPCODE_Y1 = 2,
-  SPECIAL_2_OPCODE_Y0 = 3,
-  SPECIAL_2_OPCODE_Y1 = 3,
-  SPECIAL_3_OPCODE_Y0 = 4,
-  SPECIAL_3_OPCODE_Y1 = 4,
-  SPECIAL_4_OPCODE_Y0 = 5,
-  SPECIAL_4_OPCODE_Y1 = 5,
-  SPECIAL_5_OPCODE_Y0 = 6,
-  SPECIAL_5_OPCODE_Y1 = 6,
-  SPECIAL_6_OPCODE_Y0 = 7,
-  SPECIAL_7_OPCODE_Y0 = 8,
-  SRAB_SPECIAL_0_OPCODE_X0 = 88,
-  SRAB_SPECIAL_0_OPCODE_X1 = 58,
-  SRAH_SPECIAL_0_OPCODE_X0 = 89,
-  SRAH_SPECIAL_0_OPCODE_X1 = 59,
-  SRAIB_SHUN_0_OPCODE_X0 = 8,
-  SRAIB_SHUN_0_OPCODE_X1 = 8,
-  SRAIH_SHUN_0_OPCODE_X0 = 9,
-  SRAIH_SHUN_0_OPCODE_X1 = 9,
-  SRAI_SHUN_0_OPCODE_X0 = 10,
-  SRAI_SHUN_0_OPCODE_X1 = 10,
-  SRAI_SHUN_0_OPCODE_Y0 = 4,
-  SRAI_SHUN_0_OPCODE_Y1 = 4,
-  SRA_SPECIAL_0_OPCODE_X0 = 90,
-  SRA_SPECIAL_0_OPCODE_X1 = 60,
-  SRA_SPECIAL_3_OPCODE_Y0 = 3,
-  SRA_SPECIAL_3_OPCODE_Y1 = 3,
-  SUBBS_U_SPECIAL_0_OPCODE_X0 = 100,
-  SUBBS_U_SPECIAL_0_OPCODE_X1 = 70,
-  SUBB_SPECIAL_0_OPCODE_X0 = 91,
-  SUBB_SPECIAL_0_OPCODE_X1 = 61,
-  SUBHS_SPECIAL_0_OPCODE_X0 = 101,
-  SUBHS_SPECIAL_0_OPCODE_X1 = 71,
-  SUBH_SPECIAL_0_OPCODE_X0 = 92,
-  SUBH_SPECIAL_0_OPCODE_X1 = 62,
-  SUBS_SPECIAL_0_OPCODE_X0 = 97,
-  SUBS_SPECIAL_0_OPCODE_X1 = 67,
-  SUB_SPECIAL_0_OPCODE_X0 = 93,
-  SUB_SPECIAL_0_OPCODE_X1 = 63,
-  SUB_SPECIAL_0_OPCODE_Y0 = 3,
-  SUB_SPECIAL_0_OPCODE_Y1 = 3,
-  SWADD_IMM_0_OPCODE_X1 = 30,
-  SWINT0_UN_0_SHUN_0_OPCODE_X1 = 18,
-  SWINT1_UN_0_SHUN_0_OPCODE_X1 = 19,
-  SWINT2_UN_0_SHUN_0_OPCODE_X1 = 20,
-  SWINT3_UN_0_SHUN_0_OPCODE_X1 = 21,
-  SW_OPCODE_Y2 = 7,
-  SW_SPECIAL_0_OPCODE_X1 = 64,
-  TBLIDXB0_UN_0_SHUN_0_OPCODE_X0 = 8,
-  TBLIDXB0_UN_0_SHUN_0_OPCODE_Y0 = 8,
-  TBLIDXB1_UN_0_SHUN_0_OPCODE_X0 = 9,
-  TBLIDXB1_UN_0_SHUN_0_OPCODE_Y0 = 9,
-  TBLIDXB2_UN_0_SHUN_0_OPCODE_X0 = 10,
-  TBLIDXB2_UN_0_SHUN_0_OPCODE_Y0 = 10,
-  TBLIDXB3_UN_0_SHUN_0_OPCODE_X0 = 11,
-  TBLIDXB3_UN_0_SHUN_0_OPCODE_Y0 = 11,
-  TNS_UN_0_SHUN_0_OPCODE_X1 = 22,
-  UN_0_SHUN_0_OPCODE_X0 = 11,
-  UN_0_SHUN_0_OPCODE_X1 = 11,
-  UN_0_SHUN_0_OPCODE_Y0 = 5,
-  UN_0_SHUN_0_OPCODE_Y1 = 5,
-  WH64_UN_0_SHUN_0_OPCODE_X1 = 23,
-  XORI_IMM_0_OPCODE_X0 = 2,
-  XORI_IMM_0_OPCODE_X1 = 21,
-  XOR_SPECIAL_0_OPCODE_X0 = 94,
-  XOR_SPECIAL_0_OPCODE_X1 = 65,
-  XOR_SPECIAL_2_OPCODE_Y0 = 3,
-  XOR_SPECIAL_2_OPCODE_Y1 = 3
-};
-
-#endif /* !_TILE_OPCODE_CONSTANTS_H */
index 5e2d033..6348e59 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef _ASM_TILE_SIGCONTEXT_H
 #define _ASM_TILE_SIGCONTEXT_H
 
+/* Don't pollute the namespace since <signal.h> includes this file. */
+#define __need_int_reg_t
 #include <arch/abi.h>
 
 /*
  * but is simplified since we know the fault is from userspace.
  */
 struct sigcontext {
-       uint_reg_t gregs[53];   /* General-purpose registers.  */
-       uint_reg_t tp;          /* Aliases gregs[TREG_TP].  */
-       uint_reg_t sp;          /* Aliases gregs[TREG_SP].  */
-       uint_reg_t lr;          /* Aliases gregs[TREG_LR].  */
-       uint_reg_t pc;          /* Program counter.  */
-       uint_reg_t ics;         /* In Interrupt Critical Section?  */
-       uint_reg_t faultnum;    /* Fault number.  */
-       uint_reg_t pad[5];
+       __uint_reg_t gregs[53]; /* General-purpose registers.  */
+       __uint_reg_t tp;        /* Aliases gregs[TREG_TP].  */
+       __uint_reg_t sp;        /* Aliases gregs[TREG_SP].  */
+       __uint_reg_t lr;        /* Aliases gregs[TREG_LR].  */
+       __uint_reg_t pc;        /* Program counter.  */
+       __uint_reg_t ics;       /* In Interrupt Critical Section?  */
+       __uint_reg_t faultnum;  /* Fault number.  */
+       __uint_reg_t pad[5];
 };
 
 #endif /* _ASM_TILE_SIGCONTEXT_H */
similarity index 56%
rename from arch/tile/include/asm/opcode-tile.h
rename to arch/tile/include/asm/tile-desc.h
index ba38959..43849bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
  *
  *   This program is free software; you can redistribute it and/or
  *   modify it under the terms of the GNU General Public License
  *   more details.
  */
 
-#ifndef _ASM_TILE_OPCODE_TILE_H
-#define _ASM_TILE_OPCODE_TILE_H
-
-#include <arch/chip.h>
-
-#if CHIP_WORD_SIZE() == 64
-#include <asm/opcode-tile_64.h>
+#ifndef __tilegx__
+#include <asm/tile-desc_32.h>
 #else
-#include <asm/opcode-tile_32.h>
+#include <asm/tile-desc_64.h>
 #endif
-
-/* These definitions are not correct for TILE64, so just avoid them. */
-#undef TILE_ELF_MACHINE_CODE
-#undef TILE_ELF_NAME
-
-#endif /* _ASM_TILE_OPCODE_TILE_H */
diff --git a/arch/tile/include/asm/tile-desc_32.h b/arch/tile/include/asm/tile-desc_32.h
new file mode 100644 (file)
index 0000000..f09c5c4
--- /dev/null
@@ -0,0 +1,553 @@
+/* TILEPro opcode information.
+ *
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ *
+ *
+ *
+ *
+ */
+
+#ifndef opcode_tilepro_h
+#define opcode_tilepro_h
+
+#include <arch/opcode.h>
+
+
+enum
+{
+  TILEPRO_MAX_OPERANDS = 5 /* mm */
+};
+
+typedef enum
+{
+  TILEPRO_OPC_BPT,
+  TILEPRO_OPC_INFO,
+  TILEPRO_OPC_INFOL,
+  TILEPRO_OPC_J,
+  TILEPRO_OPC_JAL,
+  TILEPRO_OPC_MOVE,
+  TILEPRO_OPC_MOVE_SN,
+  TILEPRO_OPC_MOVEI,
+  TILEPRO_OPC_MOVEI_SN,
+  TILEPRO_OPC_MOVELI,
+  TILEPRO_OPC_MOVELI_SN,
+  TILEPRO_OPC_MOVELIS,
+  TILEPRO_OPC_PREFETCH,
+  TILEPRO_OPC_RAISE,
+  TILEPRO_OPC_ADD,
+  TILEPRO_OPC_ADD_SN,
+  TILEPRO_OPC_ADDB,
+  TILEPRO_OPC_ADDB_SN,
+  TILEPRO_OPC_ADDBS_U,
+  TILEPRO_OPC_ADDBS_U_SN,
+  TILEPRO_OPC_ADDH,
+  TILEPRO_OPC_ADDH_SN,
+  TILEPRO_OPC_ADDHS,
+  TILEPRO_OPC_ADDHS_SN,
+  TILEPRO_OPC_ADDI,
+  TILEPRO_OPC_ADDI_SN,
+  TILEPRO_OPC_ADDIB,
+  TILEPRO_OPC_ADDIB_SN,
+  TILEPRO_OPC_ADDIH,
+  TILEPRO_OPC_ADDIH_SN,
+  TILEPRO_OPC_ADDLI,
+  TILEPRO_OPC_ADDLI_SN,
+  TILEPRO_OPC_ADDLIS,
+  TILEPRO_OPC_ADDS,
+  TILEPRO_OPC_ADDS_SN,
+  TILEPRO_OPC_ADIFFB_U,
+  TILEPRO_OPC_ADIFFB_U_SN,
+  TILEPRO_OPC_ADIFFH,
+  TILEPRO_OPC_ADIFFH_SN,
+  TILEPRO_OPC_AND,
+  TILEPRO_OPC_AND_SN,
+  TILEPRO_OPC_ANDI,
+  TILEPRO_OPC_ANDI_SN,
+  TILEPRO_OPC_AULI,
+  TILEPRO_OPC_AVGB_U,
+  TILEPRO_OPC_AVGB_U_SN,
+  TILEPRO_OPC_AVGH,
+  TILEPRO_OPC_AVGH_SN,
+  TILEPRO_OPC_BBNS,
+  TILEPRO_OPC_BBNS_SN,
+  TILEPRO_OPC_BBNST,
+  TILEPRO_OPC_BBNST_SN,
+  TILEPRO_OPC_BBS,
+  TILEPRO_OPC_BBS_SN,
+  TILEPRO_OPC_BBST,
+  TILEPRO_OPC_BBST_SN,
+  TILEPRO_OPC_BGEZ,
+  TILEPRO_OPC_BGEZ_SN,
+  TILEPRO_OPC_BGEZT,
+  TILEPRO_OPC_BGEZT_SN,
+  TILEPRO_OPC_BGZ,
+  TILEPRO_OPC_BGZ_SN,
+  TILEPRO_OPC_BGZT,
+  TILEPRO_OPC_BGZT_SN,
+  TILEPRO_OPC_BITX,
+  TILEPRO_OPC_BITX_SN,
+  TILEPRO_OPC_BLEZ,
+  TILEPRO_OPC_BLEZ_SN,
+  TILEPRO_OPC_BLEZT,
+  TILEPRO_OPC_BLEZT_SN,
+  TILEPRO_OPC_BLZ,
+  TILEPRO_OPC_BLZ_SN,
+  TILEPRO_OPC_BLZT,
+  TILEPRO_OPC_BLZT_SN,
+  TILEPRO_OPC_BNZ,
+  TILEPRO_OPC_BNZ_SN,
+  TILEPRO_OPC_BNZT,
+  TILEPRO_OPC_BNZT_SN,
+  TILEPRO_OPC_BYTEX,
+  TILEPRO_OPC_BYTEX_SN,
+  TILEPRO_OPC_BZ,
+  TILEPRO_OPC_BZ_SN,
+  TILEPRO_OPC_BZT,
+  TILEPRO_OPC_BZT_SN,
+  TILEPRO_OPC_CLZ,
+  TILEPRO_OPC_CLZ_SN,
+  TILEPRO_OPC_CRC32_32,
+  TILEPRO_OPC_CRC32_32_SN,
+  TILEPRO_OPC_CRC32_8,
+  TILEPRO_OPC_CRC32_8_SN,
+  TILEPRO_OPC_CTZ,
+  TILEPRO_OPC_CTZ_SN,
+  TILEPRO_OPC_DRAIN,
+  TILEPRO_OPC_DTLBPR,
+  TILEPRO_OPC_DWORD_ALIGN,
+  TILEPRO_OPC_DWORD_ALIGN_SN,
+  TILEPRO_OPC_FINV,
+  TILEPRO_OPC_FLUSH,
+  TILEPRO_OPC_FNOP,
+  TILEPRO_OPC_ICOH,
+  TILEPRO_OPC_ILL,
+  TILEPRO_OPC_INTHB,
+  TILEPRO_OPC_INTHB_SN,
+  TILEPRO_OPC_INTHH,
+  TILEPRO_OPC_INTHH_SN,
+  TILEPRO_OPC_INTLB,
+  TILEPRO_OPC_INTLB_SN,
+  TILEPRO_OPC_INTLH,
+  TILEPRO_OPC_INTLH_SN,
+  TILEPRO_OPC_INV,
+  TILEPRO_OPC_IRET,
+  TILEPRO_OPC_JALB,
+  TILEPRO_OPC_JALF,
+  TILEPRO_OPC_JALR,
+  TILEPRO_OPC_JALRP,
+  TILEPRO_OPC_JB,
+  TILEPRO_OPC_JF,
+  TILEPRO_OPC_JR,
+  TILEPRO_OPC_JRP,
+  TILEPRO_OPC_LB,
+  TILEPRO_OPC_LB_SN,
+  TILEPRO_OPC_LB_U,
+  TILEPRO_OPC_LB_U_SN,
+  TILEPRO_OPC_LBADD,
+  TILEPRO_OPC_LBADD_SN,
+  TILEPRO_OPC_LBADD_U,
+  TILEPRO_OPC_LBADD_U_SN,
+  TILEPRO_OPC_LH,
+  TILEPRO_OPC_LH_SN,
+  TILEPRO_OPC_LH_U,
+  TILEPRO_OPC_LH_U_SN,
+  TILEPRO_OPC_LHADD,
+  TILEPRO_OPC_LHADD_SN,
+  TILEPRO_OPC_LHADD_U,
+  TILEPRO_OPC_LHADD_U_SN,
+  TILEPRO_OPC_LNK,
+  TILEPRO_OPC_LNK_SN,
+  TILEPRO_OPC_LW,
+  TILEPRO_OPC_LW_SN,
+  TILEPRO_OPC_LW_NA,
+  TILEPRO_OPC_LW_NA_SN,
+  TILEPRO_OPC_LWADD,
+  TILEPRO_OPC_LWADD_SN,
+  TILEPRO_OPC_LWADD_NA,
+  TILEPRO_OPC_LWADD_NA_SN,
+  TILEPRO_OPC_MAXB_U,
+  TILEPRO_OPC_MAXB_U_SN,
+  TILEPRO_OPC_MAXH,
+  TILEPRO_OPC_MAXH_SN,
+  TILEPRO_OPC_MAXIB_U,
+  TILEPRO_OPC_MAXIB_U_SN,
+  TILEPRO_OPC_MAXIH,
+  TILEPRO_OPC_MAXIH_SN,
+  TILEPRO_OPC_MF,
+  TILEPRO_OPC_MFSPR,
+  TILEPRO_OPC_MINB_U,
+  TILEPRO_OPC_MINB_U_SN,
+  TILEPRO_OPC_MINH,
+  TILEPRO_OPC_MINH_SN,
+  TILEPRO_OPC_MINIB_U,
+  TILEPRO_OPC_MINIB_U_SN,
+  TILEPRO_OPC_MINIH,
+  TILEPRO_OPC_MINIH_SN,
+  TILEPRO_OPC_MM,
+  TILEPRO_OPC_MNZ,
+  TILEPRO_OPC_MNZ_SN,
+  TILEPRO_OPC_MNZB,
+  TILEPRO_OPC_MNZB_SN,
+  TILEPRO_OPC_MNZH,
+  TILEPRO_OPC_MNZH_SN,
+  TILEPRO_OPC_MTSPR,
+  TILEPRO_OPC_MULHH_SS,
+  TILEPRO_OPC_MULHH_SS_SN,
+  TILEPRO_OPC_MULHH_SU,
+  TILEPRO_OPC_MULHH_SU_SN,
+  TILEPRO_OPC_MULHH_UU,
+  TILEPRO_OPC_MULHH_UU_SN,
+  TILEPRO_OPC_MULHHA_SS,
+  TILEPRO_OPC_MULHHA_SS_SN,
+  TILEPRO_OPC_MULHHA_SU,
+  TILEPRO_OPC_MULHHA_SU_SN,
+  TILEPRO_OPC_MULHHA_UU,
+  TILEPRO_OPC_MULHHA_UU_SN,
+  TILEPRO_OPC_MULHHSA_UU,
+  TILEPRO_OPC_MULHHSA_UU_SN,
+  TILEPRO_OPC_MULHL_SS,
+  TILEPRO_OPC_MULHL_SS_SN,
+  TILEPRO_OPC_MULHL_SU,
+  TILEPRO_OPC_MULHL_SU_SN,
+  TILEPRO_OPC_MULHL_US,
+  TILEPRO_OPC_MULHL_US_SN,
+  TILEPRO_OPC_MULHL_UU,
+  TILEPRO_OPC_MULHL_UU_SN,
+  TILEPRO_OPC_MULHLA_SS,
+  TILEPRO_OPC_MULHLA_SS_SN,
+  TILEPRO_OPC_MULHLA_SU,
+  TILEPRO_OPC_MULHLA_SU_SN,
+  TILEPRO_OPC_MULHLA_US,
+  TILEPRO_OPC_MULHLA_US_SN,
+  TILEPRO_OPC_MULHLA_UU,
+  TILEPRO_OPC_MULHLA_UU_SN,
+  TILEPRO_OPC_MULHLSA_UU,
+  TILEPRO_OPC_MULHLSA_UU_SN,
+  TILEPRO_OPC_MULLL_SS,
+  TILEPRO_OPC_MULLL_SS_SN,
+  TILEPRO_OPC_MULLL_SU,
+  TILEPRO_OPC_MULLL_SU_SN,
+  TILEPRO_OPC_MULLL_UU,
+  TILEPRO_OPC_MULLL_UU_SN,
+  TILEPRO_OPC_MULLLA_SS,
+  TILEPRO_OPC_MULLLA_SS_SN,
+  TILEPRO_OPC_MULLLA_SU,
+  TILEPRO_OPC_MULLLA_SU_SN,
+  TILEPRO_OPC_MULLLA_UU,
+  TILEPRO_OPC_MULLLA_UU_SN,
+  TILEPRO_OPC_MULLLSA_UU,
+  TILEPRO_OPC_MULLLSA_UU_SN,
+  TILEPRO_OPC_MVNZ,
+  TILEPRO_OPC_MVNZ_SN,
+  TILEPRO_OPC_MVZ,
+  TILEPRO_OPC_MVZ_SN,
+  TILEPRO_OPC_MZ,
+  TILEPRO_OPC_MZ_SN,
+  TILEPRO_OPC_MZB,
+  TILEPRO_OPC_MZB_SN,
+  TILEPRO_OPC_MZH,
+  TILEPRO_OPC_MZH_SN,
+  TILEPRO_OPC_NAP,
+  TILEPRO_OPC_NOP,
+  TILEPRO_OPC_NOR,
+  TILEPRO_OPC_NOR_SN,
+  TILEPRO_OPC_OR,
+  TILEPRO_OPC_OR_SN,
+  TILEPRO_OPC_ORI,
+  TILEPRO_OPC_ORI_SN,
+  TILEPRO_OPC_PACKBS_U,
+  TILEPRO_OPC_PACKBS_U_SN,
+  TILEPRO_OPC_PACKHB,
+  TILEPRO_OPC_PACKHB_SN,
+  TILEPRO_OPC_PACKHS,
+  TILEPRO_OPC_PACKHS_SN,
+  TILEPRO_OPC_PACKLB,
+  TILEPRO_OPC_PACKLB_SN,
+  TILEPRO_OPC_PCNT,
+  TILEPRO_OPC_PCNT_SN,
+  TILEPRO_OPC_RL,
+  TILEPRO_OPC_RL_SN,
+  TILEPRO_OPC_RLI,
+  TILEPRO_OPC_RLI_SN,
+  TILEPRO_OPC_S1A,
+  TILEPRO_OPC_S1A_SN,
+  TILEPRO_OPC_S2A,
+  TILEPRO_OPC_S2A_SN,
+  TILEPRO_OPC_S3A,
+  TILEPRO_OPC_S3A_SN,
+  TILEPRO_OPC_SADAB_U,
+  TILEPRO_OPC_SADAB_U_SN,
+  TILEPRO_OPC_SADAH,
+  TILEPRO_OPC_SADAH_SN,
+  TILEPRO_OPC_SADAH_U,
+  TILEPRO_OPC_SADAH_U_SN,
+  TILEPRO_OPC_SADB_U,
+  TILEPRO_OPC_SADB_U_SN,
+  TILEPRO_OPC_SADH,
+  TILEPRO_OPC_SADH_SN,
+  TILEPRO_OPC_SADH_U,
+  TILEPRO_OPC_SADH_U_SN,
+  TILEPRO_OPC_SB,
+  TILEPRO_OPC_SBADD,
+  TILEPRO_OPC_SEQ,
+  TILEPRO_OPC_SEQ_SN,
+  TILEPRO_OPC_SEQB,
+  TILEPRO_OPC_SEQB_SN,
+  TILEPRO_OPC_SEQH,
+  TILEPRO_OPC_SEQH_SN,
+  TILEPRO_OPC_SEQI,
+  TILEPRO_OPC_SEQI_SN,
+  TILEPRO_OPC_SEQIB,
+  TILEPRO_OPC_SEQIB_SN,
+  TILEPRO_OPC_SEQIH,
+  TILEPRO_OPC_SEQIH_SN,
+  TILEPRO_OPC_SH,
+  TILEPRO_OPC_SHADD,
+  TILEPRO_OPC_SHL,
+  TILEPRO_OPC_SHL_SN,
+  TILEPRO_OPC_SHLB,
+  TILEPRO_OPC_SHLB_SN,
+  TILEPRO_OPC_SHLH,
+  TILEPRO_OPC_SHLH_SN,
+  TILEPRO_OPC_SHLI,
+  TILEPRO_OPC_SHLI_SN,
+  TILEPRO_OPC_SHLIB,
+  TILEPRO_OPC_SHLIB_SN,
+  TILEPRO_OPC_SHLIH,
+  TILEPRO_OPC_SHLIH_SN,
+  TILEPRO_OPC_SHR,
+  TILEPRO_OPC_SHR_SN,
+  TILEPRO_OPC_SHRB,
+  TILEPRO_OPC_SHRB_SN,
+  TILEPRO_OPC_SHRH,
+  TILEPRO_OPC_SHRH_SN,
+  TILEPRO_OPC_SHRI,
+  TILEPRO_OPC_SHRI_SN,
+  TILEPRO_OPC_SHRIB,
+  TILEPRO_OPC_SHRIB_SN,
+  TILEPRO_OPC_SHRIH,
+  TILEPRO_OPC_SHRIH_SN,
+  TILEPRO_OPC_SLT,
+  TILEPRO_OPC_SLT_SN,
+  TILEPRO_OPC_SLT_U,
+  TILEPRO_OPC_SLT_U_SN,
+  TILEPRO_OPC_SLTB,
+  TILEPRO_OPC_SLTB_SN,
+  TILEPRO_OPC_SLTB_U,
+  TILEPRO_OPC_SLTB_U_SN,
+  TILEPRO_OPC_SLTE,
+  TILEPRO_OPC_SLTE_SN,
+  TILEPRO_OPC_SLTE_U,
+  TILEPRO_OPC_SLTE_U_SN,
+  TILEPRO_OPC_SLTEB,
+  TILEPRO_OPC_SLTEB_SN,
+  TILEPRO_OPC_SLTEB_U,
+  TILEPRO_OPC_SLTEB_U_SN,
+  TILEPRO_OPC_SLTEH,
+  TILEPRO_OPC_SLTEH_SN,
+  TILEPRO_OPC_SLTEH_U,
+  TILEPRO_OPC_SLTEH_U_SN,
+  TILEPRO_OPC_SLTH,
+  TILEPRO_OPC_SLTH_SN,
+  TILEPRO_OPC_SLTH_U,
+  TILEPRO_OPC_SLTH_U_SN,
+  TILEPRO_OPC_SLTI,
+  TILEPRO_OPC_SLTI_SN,
+  TILEPRO_OPC_SLTI_U,
+  TILEPRO_OPC_SLTI_U_SN,
+  TILEPRO_OPC_SLTIB,
+  TILEPRO_OPC_SLTIB_SN,
+  TILEPRO_OPC_SLTIB_U,
+  TILEPRO_OPC_SLTIB_U_SN,
+  TILEPRO_OPC_SLTIH,
+  TILEPRO_OPC_SLTIH_SN,
+  TILEPRO_OPC_SLTIH_U,
+  TILEPRO_OPC_SLTIH_U_SN,
+  TILEPRO_OPC_SNE,
+  TILEPRO_OPC_SNE_SN,
+  TILEPRO_OPC_SNEB,
+  TILEPRO_OPC_SNEB_SN,
+  TILEPRO_OPC_SNEH,
+  TILEPRO_OPC_SNEH_SN,
+  TILEPRO_OPC_SRA,
+  TILEPRO_OPC_SRA_SN,
+  TILEPRO_OPC_SRAB,
+  TILEPRO_OPC_SRAB_SN,
+  TILEPRO_OPC_SRAH,
+  TILEPRO_OPC_SRAH_SN,
+  TILEPRO_OPC_SRAI,
+  TILEPRO_OPC_SRAI_SN,
+  TILEPRO_OPC_SRAIB,
+  TILEPRO_OPC_SRAIB_SN,
+  TILEPRO_OPC_SRAIH,
+  TILEPRO_OPC_SRAIH_SN,
+  TILEPRO_OPC_SUB,
+  TILEPRO_OPC_SUB_SN,
+  TILEPRO_OPC_SUBB,
+  TILEPRO_OPC_SUBB_SN,
+  TILEPRO_OPC_SUBBS_U,
+  TILEPRO_OPC_SUBBS_U_SN,
+  TILEPRO_OPC_SUBH,
+  TILEPRO_OPC_SUBH_SN,
+  TILEPRO_OPC_SUBHS,
+  TILEPRO_OPC_SUBHS_SN,
+  TILEPRO_OPC_SUBS,
+  TILEPRO_OPC_SUBS_SN,
+  TILEPRO_OPC_SW,
+  TILEPRO_OPC_SWADD,
+  TILEPRO_OPC_SWINT0,
+  TILEPRO_OPC_SWINT1,
+  TILEPRO_OPC_SWINT2,
+  TILEPRO_OPC_SWINT3,
+  TILEPRO_OPC_TBLIDXB0,
+  TILEPRO_OPC_TBLIDXB0_SN,
+  TILEPRO_OPC_TBLIDXB1,
+  TILEPRO_OPC_TBLIDXB1_SN,
+  TILEPRO_OPC_TBLIDXB2,
+  TILEPRO_OPC_TBLIDXB2_SN,
+  TILEPRO_OPC_TBLIDXB3,
+  TILEPRO_OPC_TBLIDXB3_SN,
+  TILEPRO_OPC_TNS,
+  TILEPRO_OPC_TNS_SN,
+  TILEPRO_OPC_WH64,
+  TILEPRO_OPC_XOR,
+  TILEPRO_OPC_XOR_SN,
+  TILEPRO_OPC_XORI,
+  TILEPRO_OPC_XORI_SN,
+  TILEPRO_OPC_NONE
+} tilepro_mnemonic;
+
+
+
+
+typedef enum
+{
+  TILEPRO_PIPELINE_X0,
+  TILEPRO_PIPELINE_X1,
+  TILEPRO_PIPELINE_Y0,
+  TILEPRO_PIPELINE_Y1,
+  TILEPRO_PIPELINE_Y2,
+} tilepro_pipeline;
+
+#define tilepro_is_x_pipeline(p) ((int)(p) <= (int)TILEPRO_PIPELINE_X1)
+
+typedef enum
+{
+  TILEPRO_OP_TYPE_REGISTER,
+  TILEPRO_OP_TYPE_IMMEDIATE,
+  TILEPRO_OP_TYPE_ADDRESS,
+  TILEPRO_OP_TYPE_SPR
+} tilepro_operand_type;
+
+struct tilepro_operand
+{
+  /* Is this operand a register, immediate or address? */
+  tilepro_operand_type type;
+
+  /* The default relocation type for this operand.  */
+  signed int default_reloc : 16;
+
+  /* How many bits is this value? (used for range checking) */
+  unsigned int num_bits : 5;
+
+  /* Is the value signed? (used for range checking) */
+  unsigned int is_signed : 1;
+
+  /* Is this operand a source register? */
+  unsigned int is_src_reg : 1;
+
+  /* Is this operand written? (i.e. is it a destination register) */
+  unsigned int is_dest_reg : 1;
+
+  /* Is this operand PC-relative? */
+  unsigned int is_pc_relative : 1;
+
+  /* By how many bits do we right shift the value before inserting? */
+  unsigned int rightshift : 2;
+
+  /* Return the bits for this operand to be ORed into an existing bundle. */
+  tilepro_bundle_bits (*insert) (int op);
+
+  /* Extract this operand and return it. */
+  unsigned int (*extract) (tilepro_bundle_bits bundle);
+};
+
+
+extern const struct tilepro_operand tilepro_operands[];
+
+/* One finite-state machine per pipe for rapid instruction decoding. */
+extern const unsigned short * const
+tilepro_bundle_decoder_fsms[TILEPRO_NUM_PIPELINE_ENCODINGS];
+
+
+struct tilepro_opcode
+{
+  /* The opcode mnemonic, e.g. "add" */
+  const char *name;
+
+  /* The enum value for this mnemonic. */
+  tilepro_mnemonic mnemonic;
+
+  /* A bit mask of which of the five pipes this instruction
+     is compatible with:
+     X0  0x01
+     X1  0x02
+     Y0  0x04
+     Y1  0x08
+     Y2  0x10 */
+  unsigned char pipes;
+
+  /* How many operands are there? */
+  unsigned char num_operands;
+
+  /* Which register does this write implicitly, or TREG_ZERO if none? */
+  unsigned char implicitly_written_register;
+
+  /* Can this be bundled with other instructions (almost always true). */
+  unsigned char can_bundle;
+
+  /* The description of the operands. Each of these is an
+   * index into the tilepro_operands[] table. */
+  unsigned char operands[TILEPRO_NUM_PIPELINE_ENCODINGS][TILEPRO_MAX_OPERANDS];
+
+};
+
+extern const struct tilepro_opcode tilepro_opcodes[];
+
+
+/* Used for non-textual disassembly into structs. */
+struct tilepro_decoded_instruction
+{
+  const struct tilepro_opcode *opcode;
+  const struct tilepro_operand *operands[TILEPRO_MAX_OPERANDS];
+  int operand_values[TILEPRO_MAX_OPERANDS];
+};
+
+
+/* Disassemble a bundle into a struct for machine processing. */
+extern int parse_insn_tilepro(tilepro_bundle_bits bits,
+                              unsigned int pc,
+                              struct tilepro_decoded_instruction
+                              decoded[TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE]);
+
+
+/* Given a set of bundle bits and a specific pipe, returns which
+ * instruction the bundle contains in that pipe.
+ */
+extern const struct tilepro_opcode *
+find_opcode(tilepro_bundle_bits bits, tilepro_pipeline pipe);
+
+
+
+#endif /* opcode_tilepro_h */
diff --git a/arch/tile/include/asm/tile-desc_64.h b/arch/tile/include/asm/tile-desc_64.h
new file mode 100644 (file)
index 0000000..1819efc
--- /dev/null
@@ -0,0 +1,483 @@
+/* TILE-Gx opcode information.
+ *
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ *
+ *
+ *
+ *
+ */
+
+#ifndef opcode_tile_h
+#define opcode_tile_h
+
+#include <arch/opcode.h>
+
+
+enum
+{
+  TILEGX_MAX_OPERANDS = 4 /* bfexts */
+};
+
+typedef enum
+{
+  TILEGX_OPC_BPT,
+  TILEGX_OPC_INFO,
+  TILEGX_OPC_INFOL,
+  TILEGX_OPC_MOVE,
+  TILEGX_OPC_MOVEI,
+  TILEGX_OPC_MOVELI,
+  TILEGX_OPC_PREFETCH,
+  TILEGX_OPC_PREFETCH_ADD_L1,
+  TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
+  TILEGX_OPC_PREFETCH_ADD_L2,
+  TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
+  TILEGX_OPC_PREFETCH_ADD_L3,
+  TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+  TILEGX_OPC_PREFETCH_L1,
+  TILEGX_OPC_PREFETCH_L1_FAULT,
+  TILEGX_OPC_PREFETCH_L2,
+  TILEGX_OPC_PREFETCH_L2_FAULT,
+  TILEGX_OPC_PREFETCH_L3,
+  TILEGX_OPC_PREFETCH_L3_FAULT,
+  TILEGX_OPC_RAISE,
+  TILEGX_OPC_ADD,
+  TILEGX_OPC_ADDI,
+  TILEGX_OPC_ADDLI,
+  TILEGX_OPC_ADDX,
+  TILEGX_OPC_ADDXI,
+  TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXSC,
+  TILEGX_OPC_AND,
+  TILEGX_OPC_ANDI,
+  TILEGX_OPC_BEQZ,
+  TILEGX_OPC_BEQZT,
+  TILEGX_OPC_BFEXTS,
+  TILEGX_OPC_BFEXTU,
+  TILEGX_OPC_BFINS,
+  TILEGX_OPC_BGEZ,
+  TILEGX_OPC_BGEZT,
+  TILEGX_OPC_BGTZ,
+  TILEGX_OPC_BGTZT,
+  TILEGX_OPC_BLBC,
+  TILEGX_OPC_BLBCT,
+  TILEGX_OPC_BLBS,
+  TILEGX_OPC_BLBST,
+  TILEGX_OPC_BLEZ,
+  TILEGX_OPC_BLEZT,
+  TILEGX_OPC_BLTZ,
+  TILEGX_OPC_BLTZT,
+  TILEGX_OPC_BNEZ,
+  TILEGX_OPC_BNEZT,
+  TILEGX_OPC_CLZ,
+  TILEGX_OPC_CMOVEQZ,
+  TILEGX_OPC_CMOVNEZ,
+  TILEGX_OPC_CMPEQ,
+  TILEGX_OPC_CMPEQI,
+  TILEGX_OPC_CMPEXCH,
+  TILEGX_OPC_CMPEXCH4,
+  TILEGX_OPC_CMPLES,
+  TILEGX_OPC_CMPLEU,
+  TILEGX_OPC_CMPLTS,
+  TILEGX_OPC_CMPLTSI,
+  TILEGX_OPC_CMPLTU,
+  TILEGX_OPC_CMPLTUI,
+  TILEGX_OPC_CMPNE,
+  TILEGX_OPC_CMUL,
+  TILEGX_OPC_CMULA,
+  TILEGX_OPC_CMULAF,
+  TILEGX_OPC_CMULF,
+  TILEGX_OPC_CMULFR,
+  TILEGX_OPC_CMULH,
+  TILEGX_OPC_CMULHR,
+  TILEGX_OPC_CRC32_32,
+  TILEGX_OPC_CRC32_8,
+  TILEGX_OPC_CTZ,
+  TILEGX_OPC_DBLALIGN,
+  TILEGX_OPC_DBLALIGN2,
+  TILEGX_OPC_DBLALIGN4,
+  TILEGX_OPC_DBLALIGN6,
+  TILEGX_OPC_DRAIN,
+  TILEGX_OPC_DTLBPR,
+  TILEGX_OPC_EXCH,
+  TILEGX_OPC_EXCH4,
+  TILEGX_OPC_FDOUBLE_ADD_FLAGS,
+  TILEGX_OPC_FDOUBLE_ADDSUB,
+  TILEGX_OPC_FDOUBLE_MUL_FLAGS,
+  TILEGX_OPC_FDOUBLE_PACK1,
+  TILEGX_OPC_FDOUBLE_PACK2,
+  TILEGX_OPC_FDOUBLE_SUB_FLAGS,
+  TILEGX_OPC_FDOUBLE_UNPACK_MAX,
+  TILEGX_OPC_FDOUBLE_UNPACK_MIN,
+  TILEGX_OPC_FETCHADD,
+  TILEGX_OPC_FETCHADD4,
+  TILEGX_OPC_FETCHADDGEZ,
+  TILEGX_OPC_FETCHADDGEZ4,
+  TILEGX_OPC_FETCHAND,
+  TILEGX_OPC_FETCHAND4,
+  TILEGX_OPC_FETCHOR,
+  TILEGX_OPC_FETCHOR4,
+  TILEGX_OPC_FINV,
+  TILEGX_OPC_FLUSH,
+  TILEGX_OPC_FLUSHWB,
+  TILEGX_OPC_FNOP,
+  TILEGX_OPC_FSINGLE_ADD1,
+  TILEGX_OPC_FSINGLE_ADDSUB2,
+  TILEGX_OPC_FSINGLE_MUL1,
+  TILEGX_OPC_FSINGLE_MUL2,
+  TILEGX_OPC_FSINGLE_PACK1,
+  TILEGX_OPC_FSINGLE_PACK2,
+  TILEGX_OPC_FSINGLE_SUB1,
+  TILEGX_OPC_ICOH,
+  TILEGX_OPC_ILL,
+  TILEGX_OPC_INV,
+  TILEGX_OPC_IRET,
+  TILEGX_OPC_J,
+  TILEGX_OPC_JAL,
+  TILEGX_OPC_JALR,
+  TILEGX_OPC_JALRP,
+  TILEGX_OPC_JR,
+  TILEGX_OPC_JRP,
+  TILEGX_OPC_LD,
+  TILEGX_OPC_LD1S,
+  TILEGX_OPC_LD1S_ADD,
+  TILEGX_OPC_LD1U,
+  TILEGX_OPC_LD1U_ADD,
+  TILEGX_OPC_LD2S,
+  TILEGX_OPC_LD2S_ADD,
+  TILEGX_OPC_LD2U,
+  TILEGX_OPC_LD2U_ADD,
+  TILEGX_OPC_LD4S,
+  TILEGX_OPC_LD4S_ADD,
+  TILEGX_OPC_LD4U,
+  TILEGX_OPC_LD4U_ADD,
+  TILEGX_OPC_LD_ADD,
+  TILEGX_OPC_LDNA,
+  TILEGX_OPC_LDNA_ADD,
+  TILEGX_OPC_LDNT,
+  TILEGX_OPC_LDNT1S,
+  TILEGX_OPC_LDNT1S_ADD,
+  TILEGX_OPC_LDNT1U,
+  TILEGX_OPC_LDNT1U_ADD,
+  TILEGX_OPC_LDNT2S,
+  TILEGX_OPC_LDNT2S_ADD,
+  TILEGX_OPC_LDNT2U,
+  TILEGX_OPC_LDNT2U_ADD,
+  TILEGX_OPC_LDNT4S,
+  TILEGX_OPC_LDNT4S_ADD,
+  TILEGX_OPC_LDNT4U,
+  TILEGX_OPC_LDNT4U_ADD,
+  TILEGX_OPC_LDNT_ADD,
+  TILEGX_OPC_LNK,
+  TILEGX_OPC_MF,
+  TILEGX_OPC_MFSPR,
+  TILEGX_OPC_MM,
+  TILEGX_OPC_MNZ,
+  TILEGX_OPC_MTSPR,
+  TILEGX_OPC_MUL_HS_HS,
+  TILEGX_OPC_MUL_HS_HU,
+  TILEGX_OPC_MUL_HS_LS,
+  TILEGX_OPC_MUL_HS_LU,
+  TILEGX_OPC_MUL_HU_HU,
+  TILEGX_OPC_MUL_HU_LS,
+  TILEGX_OPC_MUL_HU_LU,
+  TILEGX_OPC_MUL_LS_LS,
+  TILEGX_OPC_MUL_LS_LU,
+  TILEGX_OPC_MUL_LU_LU,
+  TILEGX_OPC_MULA_HS_HS,
+  TILEGX_OPC_MULA_HS_HU,
+  TILEGX_OPC_MULA_HS_LS,
+  TILEGX_OPC_MULA_HS_LU,
+  TILEGX_OPC_MULA_HU_HU,
+  TILEGX_OPC_MULA_HU_LS,
+  TILEGX_OPC_MULA_HU_LU,
+  TILEGX_OPC_MULA_LS_LS,
+  TILEGX_OPC_MULA_LS_LU,
+  TILEGX_OPC_MULA_LU_LU,
+  TILEGX_OPC_MULAX,
+  TILEGX_OPC_MULX,
+  TILEGX_OPC_MZ,
+  TILEGX_OPC_NAP,
+  TILEGX_OPC_NOP,
+  TILEGX_OPC_NOR,
+  TILEGX_OPC_OR,
+  TILEGX_OPC_ORI,
+  TILEGX_OPC_PCNT,
+  TILEGX_OPC_REVBITS,
+  TILEGX_OPC_REVBYTES,
+  TILEGX_OPC_ROTL,
+  TILEGX_OPC_ROTLI,
+  TILEGX_OPC_SHL,
+  TILEGX_OPC_SHL16INSLI,
+  TILEGX_OPC_SHL1ADD,
+  TILEGX_OPC_SHL1ADDX,
+  TILEGX_OPC_SHL2ADD,
+  TILEGX_OPC_SHL2ADDX,
+  TILEGX_OPC_SHL3ADD,
+  TILEGX_OPC_SHL3ADDX,
+  TILEGX_OPC_SHLI,
+  TILEGX_OPC_SHLX,
+  TILEGX_OPC_SHLXI,
+  TILEGX_OPC_SHRS,
+  TILEGX_OPC_SHRSI,
+  TILEGX_OPC_SHRU,
+  TILEGX_OPC_SHRUI,
+  TILEGX_OPC_SHRUX,
+  TILEGX_OPC_SHRUXI,
+  TILEGX_OPC_SHUFFLEBYTES,
+  TILEGX_OPC_ST,
+  TILEGX_OPC_ST1,
+  TILEGX_OPC_ST1_ADD,
+  TILEGX_OPC_ST2,
+  TILEGX_OPC_ST2_ADD,
+  TILEGX_OPC_ST4,
+  TILEGX_OPC_ST4_ADD,
+  TILEGX_OPC_ST_ADD,
+  TILEGX_OPC_STNT,
+  TILEGX_OPC_STNT1,
+  TILEGX_OPC_STNT1_ADD,
+  TILEGX_OPC_STNT2,
+  TILEGX_OPC_STNT2_ADD,
+  TILEGX_OPC_STNT4,
+  TILEGX_OPC_STNT4_ADD,
+  TILEGX_OPC_STNT_ADD,
+  TILEGX_OPC_SUB,
+  TILEGX_OPC_SUBX,
+  TILEGX_OPC_SUBXSC,
+  TILEGX_OPC_SWINT0,
+  TILEGX_OPC_SWINT1,
+  TILEGX_OPC_SWINT2,
+  TILEGX_OPC_SWINT3,
+  TILEGX_OPC_TBLIDXB0,
+  TILEGX_OPC_TBLIDXB1,
+  TILEGX_OPC_TBLIDXB2,
+  TILEGX_OPC_TBLIDXB3,
+  TILEGX_OPC_V1ADD,
+  TILEGX_OPC_V1ADDI,
+  TILEGX_OPC_V1ADDUC,
+  TILEGX_OPC_V1ADIFFU,
+  TILEGX_OPC_V1AVGU,
+  TILEGX_OPC_V1CMPEQ,
+  TILEGX_OPC_V1CMPEQI,
+  TILEGX_OPC_V1CMPLES,
+  TILEGX_OPC_V1CMPLEU,
+  TILEGX_OPC_V1CMPLTS,
+  TILEGX_OPC_V1CMPLTSI,
+  TILEGX_OPC_V1CMPLTU,
+  TILEGX_OPC_V1CMPLTUI,
+  TILEGX_OPC_V1CMPNE,
+  TILEGX_OPC_V1DDOTPU,
+  TILEGX_OPC_V1DDOTPUA,
+  TILEGX_OPC_V1DDOTPUS,
+  TILEGX_OPC_V1DDOTPUSA,
+  TILEGX_OPC_V1DOTP,
+  TILEGX_OPC_V1DOTPA,
+  TILEGX_OPC_V1DOTPU,
+  TILEGX_OPC_V1DOTPUA,
+  TILEGX_OPC_V1DOTPUS,
+  TILEGX_OPC_V1DOTPUSA,
+  TILEGX_OPC_V1INT_H,
+  TILEGX_OPC_V1INT_L,
+  TILEGX_OPC_V1MAXU,
+  TILEGX_OPC_V1MAXUI,
+  TILEGX_OPC_V1MINU,
+  TILEGX_OPC_V1MINUI,
+  TILEGX_OPC_V1MNZ,
+  TILEGX_OPC_V1MULTU,
+  TILEGX_OPC_V1MULU,
+  TILEGX_OPC_V1MULUS,
+  TILEGX_OPC_V1MZ,
+  TILEGX_OPC_V1SADAU,
+  TILEGX_OPC_V1SADU,
+  TILEGX_OPC_V1SHL,
+  TILEGX_OPC_V1SHLI,
+  TILEGX_OPC_V1SHRS,
+  TILEGX_OPC_V1SHRSI,
+  TILEGX_OPC_V1SHRU,
+  TILEGX_OPC_V1SHRUI,
+  TILEGX_OPC_V1SUB,
+  TILEGX_OPC_V1SUBUC,
+  TILEGX_OPC_V2ADD,
+  TILEGX_OPC_V2ADDI,
+  TILEGX_OPC_V2ADDSC,
+  TILEGX_OPC_V2ADIFFS,
+  TILEGX_OPC_V2AVGS,
+  TILEGX_OPC_V2CMPEQ,
+  TILEGX_OPC_V2CMPEQI,
+  TILEGX_OPC_V2CMPLES,
+  TILEGX_OPC_V2CMPLEU,
+  TILEGX_OPC_V2CMPLTS,
+  TILEGX_OPC_V2CMPLTSI,
+  TILEGX_OPC_V2CMPLTU,
+  TILEGX_OPC_V2CMPLTUI,
+  TILEGX_OPC_V2CMPNE,
+  TILEGX_OPC_V2DOTP,
+  TILEGX_OPC_V2DOTPA,
+  TILEGX_OPC_V2INT_H,
+  TILEGX_OPC_V2INT_L,
+  TILEGX_OPC_V2MAXS,
+  TILEGX_OPC_V2MAXSI,
+  TILEGX_OPC_V2MINS,
+  TILEGX_OPC_V2MINSI,
+  TILEGX_OPC_V2MNZ,
+  TILEGX_OPC_V2MULFSC,
+  TILEGX_OPC_V2MULS,
+  TILEGX_OPC_V2MULTS,
+  TILEGX_OPC_V2MZ,
+  TILEGX_OPC_V2PACKH,
+  TILEGX_OPC_V2PACKL,
+  TILEGX_OPC_V2PACKUC,
+  TILEGX_OPC_V2SADAS,
+  TILEGX_OPC_V2SADAU,
+  TILEGX_OPC_V2SADS,
+  TILEGX_OPC_V2SADU,
+  TILEGX_OPC_V2SHL,
+  TILEGX_OPC_V2SHLI,
+  TILEGX_OPC_V2SHLSC,
+  TILEGX_OPC_V2SHRS,
+  TILEGX_OPC_V2SHRSI,
+  TILEGX_OPC_V2SHRU,
+  TILEGX_OPC_V2SHRUI,
+  TILEGX_OPC_V2SUB,
+  TILEGX_OPC_V2SUBSC,
+  TILEGX_OPC_V4ADD,
+  TILEGX_OPC_V4ADDSC,
+  TILEGX_OPC_V4INT_H,
+  TILEGX_OPC_V4INT_L,
+  TILEGX_OPC_V4PACKSC,
+  TILEGX_OPC_V4SHL,
+  TILEGX_OPC_V4SHLSC,
+  TILEGX_OPC_V4SHRS,
+  TILEGX_OPC_V4SHRU,
+  TILEGX_OPC_V4SUB,
+  TILEGX_OPC_V4SUBSC,
+  TILEGX_OPC_WH64,
+  TILEGX_OPC_XOR,
+  TILEGX_OPC_XORI,
+  TILEGX_OPC_NONE
+} tilegx_mnemonic;
+
+
+
+typedef enum
+{
+  TILEGX_PIPELINE_X0,
+  TILEGX_PIPELINE_X1,
+  TILEGX_PIPELINE_Y0,
+  TILEGX_PIPELINE_Y1,
+  TILEGX_PIPELINE_Y2,
+} tilegx_pipeline;
+
+#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)
+
+typedef enum
+{
+  TILEGX_OP_TYPE_REGISTER,
+  TILEGX_OP_TYPE_IMMEDIATE,
+  TILEGX_OP_TYPE_ADDRESS,
+  TILEGX_OP_TYPE_SPR
+} tilegx_operand_type;
+
+struct tilegx_operand
+{
+  /* Is this operand a register, immediate or address? */
+  tilegx_operand_type type;
+
+  /* The default relocation type for this operand.  */
+  signed int default_reloc : 16;
+
+  /* How many bits is this value? (used for range checking) */
+  unsigned int num_bits : 5;
+
+  /* Is the value signed? (used for range checking) */
+  unsigned int is_signed : 1;
+
+  /* Is this operand a source register? */
+  unsigned int is_src_reg : 1;
+
+  /* Is this operand written? (i.e. is it a destination register) */
+  unsigned int is_dest_reg : 1;
+
+  /* Is this operand PC-relative? */
+  unsigned int is_pc_relative : 1;
+
+  /* By how many bits do we right shift the value before inserting? */
+  unsigned int rightshift : 2;
+
+  /* Return the bits for this operand to be ORed into an existing bundle. */
+  tilegx_bundle_bits (*insert) (int op);
+
+  /* Extract this operand and return it. */
+  unsigned int (*extract) (tilegx_bundle_bits bundle);
+};
+
+
+extern const struct tilegx_operand tilegx_operands[];
+
+/* One finite-state machine per pipe for rapid instruction decoding. */
+extern const unsigned short * const
+tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS];
+
+
+struct tilegx_opcode
+{
+  /* The opcode mnemonic, e.g. "add" */
+  const char *name;
+
+  /* The enum value for this mnemonic. */
+  tilegx_mnemonic mnemonic;
+
+  /* A bit mask of which of the five pipes this instruction
+     is compatible with:
+     X0  0x01
+     X1  0x02
+     Y0  0x04
+     Y1  0x08
+     Y2  0x10 */
+  unsigned char pipes;
+
+  /* How many operands are there? */
+  unsigned char num_operands;
+
+  /* Which register does this write implicitly, or TREG_ZERO if none? */
+  unsigned char implicitly_written_register;
+
+  /* Can this be bundled with other instructions (almost always true). */
+  unsigned char can_bundle;
+
+  /* The description of the operands. Each of these is an
+   * index into the tilegx_operands[] table. */
+  unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS];
+
+};
+
+extern const struct tilegx_opcode tilegx_opcodes[];
+
+/* Used for non-textual disassembly into structs. */
+struct tilegx_decoded_instruction
+{
+  const struct tilegx_opcode *opcode;
+  const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS];
+  long long operand_values[TILEGX_MAX_OPERANDS];
+};
+
+
+/* Disassemble a bundle into a struct for machine processing. */
+extern int parse_insn_tilegx(tilegx_bundle_bits bits,
+                             unsigned long long pc,
+                             struct tilegx_decoded_instruction
+                             decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]);
+
+
+
+#endif /* opcode_tilegx_h */
index 1dc71ea..9092ce8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
  *
  *   This program is free software; you can redistribute it and/or
  *   modify it under the terms of the GNU General Public License
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <asm/backtrace.h>
-#include <asm/opcode-tile.h>
+#include <asm/tile-desc.h>
 #include <arch/abi.h>
 
 #ifdef __tilegx__
-#define tile_bundle_bits tilegx_bundle_bits
 #define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE
-#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
 #define tile_decoded_instruction tilegx_decoded_instruction
 #define tile_mnemonic tilegx_mnemonic
 #define parse_insn_tile parse_insn_tilegx
 #define OPCODE_STORE TILEGX_OPC_ST
 typedef long long bt_int_reg_t;
 #else
-#define OPCODE_STORE TILE_OPC_SW
+#define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE
+#define tile_decoded_instruction tilepro_decoded_instruction
+#define tile_mnemonic tilepro_mnemonic
+#define parse_insn_tile parse_insn_tilepro
+#define TILE_OPC_IRET TILEPRO_OPC_IRET
+#define TILE_OPC_ADDI TILEPRO_OPC_ADDI
+#define TILE_OPC_ADDLI TILEPRO_OPC_ADDLI
+#define TILE_OPC_INFO TILEPRO_OPC_INFO
+#define TILE_OPC_INFOL TILEPRO_OPC_INFOL
+#define TILE_OPC_JRP TILEPRO_OPC_JRP
+#define TILE_OPC_MOVE TILEPRO_OPC_MOVE
+#define OPCODE_STORE TILEPRO_OPC_SW
 typedef int bt_int_reg_t;
 #endif
 
index 28fa6ec..b90ab99 100644 (file)
@@ -20,9 +20,9 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
-#include <asm/opcode-tile.h>
 #include <asm/pgtable.h>
 #include <asm/homecache.h>
+#include <arch/opcode.h>
 
 #ifdef __tilegx__
 # define Elf_Rela Elf64_Rela
index 4032ca8..b7a8795 100644 (file)
@@ -25,9 +25,8 @@
 #include <linux/types.h>
 #include <linux/err.h>
 #include <asm/cacheflush.h>
-#include <asm/opcode-tile.h>
-#include <asm/opcode_constants.h>
 #include <arch/abi.h>
+#include <arch/opcode.h>
 
 #define signExtend17(val) sign_extend((val), 17)
 #define TILE_X1_MASK (0xffffffffULL << 31)
@@ -118,7 +117,7 @@ static tile_bundle_bits rewrite_load_store_unaligned(
        int val_reg, addr_reg, err, val;
 
        /* Get address and value registers */
-       if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) {
+       if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK) {
                addr_reg = get_SrcA_Y2(bundle);
                val_reg = get_SrcBDest_Y2(bundle);
        } else if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) {
@@ -229,7 +228,7 @@ P("\n");
        }
        ++unaligned_fixup_count;
 
-       if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) {
+       if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK) {
                /* Convert the Y2 instruction to a prefetch. */
                bundle &= ~(create_SrcBDest_Y2(-1) |
                            create_Opcode_Y2(-1));
@@ -389,7 +388,7 @@ void single_step_once(struct pt_regs *regs)
        state->branch_next_pc = 0;
        state->update = 0;
 
-       if (!(bundle & TILE_BUNDLE_Y_ENCODING_MASK)) {
+       if (!(bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK)) {
                /* two wide, check for control flow */
                int opcode = get_Opcode_X1(bundle);
 
index 7e31a12..dd7bd1d 100644 (file)
@@ -1,3 +1,23 @@
+/* TILEPro opcode information.
+ *
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ *
+ *
+ *
+ *
+ */
+
 /* This define is BFD_RELOC_##x for real bfd, or -1 for everyone else. */
 #define BFD_RELOC(x) -1
 
 #define TREG_SN 56
 #define TREG_ZERO 63
 
-/* FIXME: Rename this. */
-#include <asm/opcode-tile.h>
-
 #include <linux/stddef.h>
+#include <asm/tile-desc.h>
 
-const struct tile_opcode tile_opcodes[395] =
+const struct tilepro_opcode tilepro_opcodes[395] =
 {
- { "bpt", TILE_OPC_BPT, 0x2, 0, TREG_ZERO, 0,
+ { "bpt", TILEPRO_OPC_BPT, 0x2, 0, TREG_ZERO, 0,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "info", TILE_OPC_INFO, 0xf, 1, TREG_ZERO, 1,
+  { "info", TILEPRO_OPC_INFO, 0xf, 1, TREG_ZERO, 1,
     { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } },
   },
-  { "infol", TILE_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,
+  { "infol", TILEPRO_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,
     { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } },
   },
-  { "j", TILE_OPC_J, 0x2, 1, TREG_ZERO, 1,
+  { "j", TILEPRO_OPC_J, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } },
   },
-  { "jal", TILE_OPC_JAL, 0x2, 1, TREG_LR, 1,
+  { "jal", TILEPRO_OPC_JAL, 0x2, 1, TREG_LR, 1,
     { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } },
   },
-  { "move", TILE_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,
+  { "move", TILEPRO_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,
     { { 7, 8 }, { 9, 10 }, { 11, 12 }, { 13, 14 }, { 0, } },
   },
-  { "move.sn", TILE_OPC_MOVE_SN, 0x3, 2, TREG_SN, 1,
+  { "move.sn", TILEPRO_OPC_MOVE_SN, 0x3, 2, TREG_SN, 1,
     { { 7, 8 }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "movei", TILE_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,
+  { "movei", TILEPRO_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,
     { { 7, 0 }, { 9, 1 }, { 11, 2 }, { 13, 3 }, { 0, } },
   },
-  { "movei.sn", TILE_OPC_MOVEI_SN, 0x3, 2, TREG_SN, 1,
+  { "movei.sn", TILEPRO_OPC_MOVEI_SN, 0x3, 2, TREG_SN, 1,
     { { 7, 0 }, { 9, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "moveli", TILE_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,
+  { "moveli", TILEPRO_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,
     { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
   },
-  { "moveli.sn", TILE_OPC_MOVELI_SN, 0x3, 2, TREG_SN, 1,
+  { "moveli.sn", TILEPRO_OPC_MOVELI_SN, 0x3, 2, TREG_SN, 1,
     { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
   },
-  { "movelis", TILE_OPC_MOVELIS, 0x3, 2, TREG_SN, 1,
+  { "movelis", TILEPRO_OPC_MOVELIS, 0x3, 2, TREG_SN, 1,
     { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
   },
-  { "prefetch", TILE_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,
+  { "prefetch", TILEPRO_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 15 } },
   },
-  { "raise", TILE_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,
+  { "raise", TILEPRO_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "add", TILE_OPC_ADD, 0xf, 3, TREG_ZERO, 1,
+  { "add", TILEPRO_OPC_ADD, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "add.sn", TILE_OPC_ADD_SN, 0x3, 3, TREG_SN, 1,
+  { "add.sn", TILEPRO_OPC_ADD_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addb", TILE_OPC_ADDB, 0x3, 3, TREG_ZERO, 1,
+  { "addb", TILEPRO_OPC_ADDB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addb.sn", TILE_OPC_ADDB_SN, 0x3, 3, TREG_SN, 1,
+  { "addb.sn", TILEPRO_OPC_ADDB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addbs_u", TILE_OPC_ADDBS_U, 0x3, 3, TREG_ZERO, 1,
+  { "addbs_u", TILEPRO_OPC_ADDBS_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addbs_u.sn", TILE_OPC_ADDBS_U_SN, 0x3, 3, TREG_SN, 1,
+  { "addbs_u.sn", TILEPRO_OPC_ADDBS_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addh", TILE_OPC_ADDH, 0x3, 3, TREG_ZERO, 1,
+  { "addh", TILEPRO_OPC_ADDH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addh.sn", TILE_OPC_ADDH_SN, 0x3, 3, TREG_SN, 1,
+  { "addh.sn", TILEPRO_OPC_ADDH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addhs", TILE_OPC_ADDHS, 0x3, 3, TREG_ZERO, 1,
+  { "addhs", TILEPRO_OPC_ADDHS, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addhs.sn", TILE_OPC_ADDHS_SN, 0x3, 3, TREG_SN, 1,
+  { "addhs.sn", TILEPRO_OPC_ADDHS_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addi", TILE_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,
+  { "addi", TILEPRO_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
   },
-  { "addi.sn", TILE_OPC_ADDI_SN, 0x3, 3, TREG_SN, 1,
+  { "addi.sn", TILEPRO_OPC_ADDI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addib", TILE_OPC_ADDIB, 0x3, 3, TREG_ZERO, 1,
+  { "addib", TILEPRO_OPC_ADDIB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addib.sn", TILE_OPC_ADDIB_SN, 0x3, 3, TREG_SN, 1,
+  { "addib.sn", TILEPRO_OPC_ADDIB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addih", TILE_OPC_ADDIH, 0x3, 3, TREG_ZERO, 1,
+  { "addih", TILEPRO_OPC_ADDIH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addih.sn", TILE_OPC_ADDIH_SN, 0x3, 3, TREG_SN, 1,
+  { "addih.sn", TILEPRO_OPC_ADDIH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addli", TILE_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,
+  { "addli", TILEPRO_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addli.sn", TILE_OPC_ADDLI_SN, 0x3, 3, TREG_SN, 1,
+  { "addli.sn", TILEPRO_OPC_ADDLI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
   },
-  { "addlis", TILE_OPC_ADDLIS, 0x3, 3, TREG_SN, 1,
+  { "addlis", TILEPRO_OPC_ADDLIS, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
   },
-  { "adds", TILE_OPC_ADDS, 0x3, 3, TREG_ZERO, 1,
+  { "adds", TILEPRO_OPC_ADDS, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "adds.sn", TILE_OPC_ADDS_SN, 0x3, 3, TREG_SN, 1,
+  { "adds.sn", TILEPRO_OPC_ADDS_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "adiffb_u", TILE_OPC_ADIFFB_U, 0x1, 3, TREG_ZERO, 1,
+  { "adiffb_u", TILEPRO_OPC_ADIFFB_U, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "adiffb_u.sn", TILE_OPC_ADIFFB_U_SN, 0x1, 3, TREG_SN, 1,
+  { "adiffb_u.sn", TILEPRO_OPC_ADIFFB_U_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "adiffh", TILE_OPC_ADIFFH, 0x1, 3, TREG_ZERO, 1,
+  { "adiffh", TILEPRO_OPC_ADIFFH, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "adiffh.sn", TILE_OPC_ADIFFH_SN, 0x1, 3, TREG_SN, 1,
+  { "adiffh.sn", TILEPRO_OPC_ADIFFH_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "and", TILE_OPC_AND, 0xf, 3, TREG_ZERO, 1,
+  { "and", TILEPRO_OPC_AND, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "and.sn", TILE_OPC_AND_SN, 0x3, 3, TREG_SN, 1,
+  { "and.sn", TILEPRO_OPC_AND_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "andi", TILE_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,
+  { "andi", TILEPRO_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
   },
-  { "andi.sn", TILE_OPC_ANDI_SN, 0x3, 3, TREG_SN, 1,
+  { "andi.sn", TILEPRO_OPC_ANDI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "auli", TILE_OPC_AULI, 0x3, 3, TREG_ZERO, 1,
+  { "auli", TILEPRO_OPC_AULI, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
   },
-  { "avgb_u", TILE_OPC_AVGB_U, 0x1, 3, TREG_ZERO, 1,
+  { "avgb_u", TILEPRO_OPC_AVGB_U, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "avgb_u.sn", TILE_OPC_AVGB_U_SN, 0x1, 3, TREG_SN, 1,
+  { "avgb_u.sn", TILEPRO_OPC_AVGB_U_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "avgh", TILE_OPC_AVGH, 0x1, 3, TREG_ZERO, 1,
+  { "avgh", TILEPRO_OPC_AVGH, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "avgh.sn", TILE_OPC_AVGH_SN, 0x1, 3, TREG_SN, 1,
+  { "avgh.sn", TILEPRO_OPC_AVGH_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "bbns", TILE_OPC_BBNS, 0x2, 2, TREG_ZERO, 1,
+  { "bbns", TILEPRO_OPC_BBNS, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bbns.sn", TILE_OPC_BBNS_SN, 0x2, 2, TREG_SN, 1,
+  { "bbns.sn", TILEPRO_OPC_BBNS_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bbnst", TILE_OPC_BBNST, 0x2, 2, TREG_ZERO, 1,
+  { "bbnst", TILEPRO_OPC_BBNST, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bbnst.sn", TILE_OPC_BBNST_SN, 0x2, 2, TREG_SN, 1,
+  { "bbnst.sn", TILEPRO_OPC_BBNST_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bbs", TILE_OPC_BBS, 0x2, 2, TREG_ZERO, 1,
+  { "bbs", TILEPRO_OPC_BBS, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bbs.sn", TILE_OPC_BBS_SN, 0x2, 2, TREG_SN, 1,
+  { "bbs.sn", TILEPRO_OPC_BBS_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bbst", TILE_OPC_BBST, 0x2, 2, TREG_ZERO, 1,
+  { "bbst", TILEPRO_OPC_BBST, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bbst.sn", TILE_OPC_BBST_SN, 0x2, 2, TREG_SN, 1,
+  { "bbst.sn", TILEPRO_OPC_BBST_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bgez", TILE_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,
+  { "bgez", TILEPRO_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bgez.sn", TILE_OPC_BGEZ_SN, 0x2, 2, TREG_SN, 1,
+  { "bgez.sn", TILEPRO_OPC_BGEZ_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bgezt", TILE_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,
+  { "bgezt", TILEPRO_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bgezt.sn", TILE_OPC_BGEZT_SN, 0x2, 2, TREG_SN, 1,
+  { "bgezt.sn", TILEPRO_OPC_BGEZT_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bgz", TILE_OPC_BGZ, 0x2, 2, TREG_ZERO, 1,
+  { "bgz", TILEPRO_OPC_BGZ, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bgz.sn", TILE_OPC_BGZ_SN, 0x2, 2, TREG_SN, 1,
+  { "bgz.sn", TILEPRO_OPC_BGZ_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bgzt", TILE_OPC_BGZT, 0x2, 2, TREG_ZERO, 1,
+  { "bgzt", TILEPRO_OPC_BGZT, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bgzt.sn", TILE_OPC_BGZT_SN, 0x2, 2, TREG_SN, 1,
+  { "bgzt.sn", TILEPRO_OPC_BGZT_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bitx", TILE_OPC_BITX, 0x5, 2, TREG_ZERO, 1,
+  { "bitx", TILEPRO_OPC_BITX, 0x5, 2, TREG_ZERO, 1,
     { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
   },
-  { "bitx.sn", TILE_OPC_BITX_SN, 0x1, 2, TREG_SN, 1,
+  { "bitx.sn", TILEPRO_OPC_BITX_SN, 0x1, 2, TREG_SN, 1,
     { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "blez", TILE_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,
+  { "blez", TILEPRO_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "blez.sn", TILE_OPC_BLEZ_SN, 0x2, 2, TREG_SN, 1,
+  { "blez.sn", TILEPRO_OPC_BLEZ_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "blezt", TILE_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,
+  { "blezt", TILEPRO_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "blezt.sn", TILE_OPC_BLEZT_SN, 0x2, 2, TREG_SN, 1,
+  { "blezt.sn", TILEPRO_OPC_BLEZT_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "blz", TILE_OPC_BLZ, 0x2, 2, TREG_ZERO, 1,
+  { "blz", TILEPRO_OPC_BLZ, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "blz.sn", TILE_OPC_BLZ_SN, 0x2, 2, TREG_SN, 1,
+  { "blz.sn", TILEPRO_OPC_BLZ_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "blzt", TILE_OPC_BLZT, 0x2, 2, TREG_ZERO, 1,
+  { "blzt", TILEPRO_OPC_BLZT, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "blzt.sn", TILE_OPC_BLZT_SN, 0x2, 2, TREG_SN, 1,
+  { "blzt.sn", TILEPRO_OPC_BLZT_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bnz", TILE_OPC_BNZ, 0x2, 2, TREG_ZERO, 1,
+  { "bnz", TILEPRO_OPC_BNZ, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bnz.sn", TILE_OPC_BNZ_SN, 0x2, 2, TREG_SN, 1,
+  { "bnz.sn", TILEPRO_OPC_BNZ_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bnzt", TILE_OPC_BNZT, 0x2, 2, TREG_ZERO, 1,
+  { "bnzt", TILEPRO_OPC_BNZT, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bnzt.sn", TILE_OPC_BNZT_SN, 0x2, 2, TREG_SN, 1,
+  { "bnzt.sn", TILEPRO_OPC_BNZT_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bytex", TILE_OPC_BYTEX, 0x5, 2, TREG_ZERO, 1,
+  { "bytex", TILEPRO_OPC_BYTEX, 0x5, 2, TREG_ZERO, 1,
     { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
   },
-  { "bytex.sn", TILE_OPC_BYTEX_SN, 0x1, 2, TREG_SN, 1,
+  { "bytex.sn", TILEPRO_OPC_BYTEX_SN, 0x1, 2, TREG_SN, 1,
     { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "bz", TILE_OPC_BZ, 0x2, 2, TREG_ZERO, 1,
+  { "bz", TILEPRO_OPC_BZ, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bz.sn", TILE_OPC_BZ_SN, 0x2, 2, TREG_SN, 1,
+  { "bz.sn", TILEPRO_OPC_BZ_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bzt", TILE_OPC_BZT, 0x2, 2, TREG_ZERO, 1,
+  { "bzt", TILEPRO_OPC_BZT, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "bzt.sn", TILE_OPC_BZT_SN, 0x2, 2, TREG_SN, 1,
+  { "bzt.sn", TILEPRO_OPC_BZT_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
   },
-  { "clz", TILE_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,
+  { "clz", TILEPRO_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,
     { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
   },
-  { "clz.sn", TILE_OPC_CLZ_SN, 0x1, 2, TREG_SN, 1,
+  { "clz.sn", TILEPRO_OPC_CLZ_SN, 0x1, 2, TREG_SN, 1,
     { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "crc32_32", TILE_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,
+  { "crc32_32", TILEPRO_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "crc32_32.sn", TILE_OPC_CRC32_32_SN, 0x1, 3, TREG_SN, 1,
+  { "crc32_32.sn", TILEPRO_OPC_CRC32_32_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "crc32_8", TILE_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,
+  { "crc32_8", TILEPRO_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "crc32_8.sn", TILE_OPC_CRC32_8_SN, 0x1, 3, TREG_SN, 1,
+  { "crc32_8.sn", TILEPRO_OPC_CRC32_8_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "ctz", TILE_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,
+  { "ctz", TILEPRO_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,
     { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
   },
-  { "ctz.sn", TILE_OPC_CTZ_SN, 0x1, 2, TREG_SN, 1,
+  { "ctz.sn", TILEPRO_OPC_CTZ_SN, 0x1, 2, TREG_SN, 1,
     { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "drain", TILE_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,
+  { "drain", TILEPRO_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "dtlbpr", TILE_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,
+  { "dtlbpr", TILEPRO_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "dword_align", TILE_OPC_DWORD_ALIGN, 0x1, 3, TREG_ZERO, 1,
+  { "dword_align", TILEPRO_OPC_DWORD_ALIGN, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "dword_align.sn", TILE_OPC_DWORD_ALIGN_SN, 0x1, 3, TREG_SN, 1,
+  { "dword_align.sn", TILEPRO_OPC_DWORD_ALIGN_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "finv", TILE_OPC_FINV, 0x2, 1, TREG_ZERO, 1,
+  { "finv", TILEPRO_OPC_FINV, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "flush", TILE_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,
+  { "flush", TILEPRO_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "fnop", TILE_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,
+  { "fnop", TILEPRO_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,
     { {  }, {  }, {  }, {  }, { 0, } },
   },
-  { "icoh", TILE_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,
+  { "icoh", TILEPRO_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "ill", TILE_OPC_ILL, 0xa, 0, TREG_ZERO, 1,
+  { "ill", TILEPRO_OPC_ILL, 0xa, 0, TREG_ZERO, 1,
     { { 0, }, {  }, { 0, }, {  }, { 0, } },
   },
-  { "inthb", TILE_OPC_INTHB, 0x3, 3, TREG_ZERO, 1,
+  { "inthb", TILEPRO_OPC_INTHB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "inthb.sn", TILE_OPC_INTHB_SN, 0x3, 3, TREG_SN, 1,
+  { "inthb.sn", TILEPRO_OPC_INTHB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "inthh", TILE_OPC_INTHH, 0x3, 3, TREG_ZERO, 1,
+  { "inthh", TILEPRO_OPC_INTHH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "inthh.sn", TILE_OPC_INTHH_SN, 0x3, 3, TREG_SN, 1,
+  { "inthh.sn", TILEPRO_OPC_INTHH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "intlb", TILE_OPC_INTLB, 0x3, 3, TREG_ZERO, 1,
+  { "intlb", TILEPRO_OPC_INTLB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "intlb.sn", TILE_OPC_INTLB_SN, 0x3, 3, TREG_SN, 1,
+  { "intlb.sn", TILEPRO_OPC_INTLB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "intlh", TILE_OPC_INTLH, 0x3, 3, TREG_ZERO, 1,
+  { "intlh", TILEPRO_OPC_INTLH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "intlh.sn", TILE_OPC_INTLH_SN, 0x3, 3, TREG_SN, 1,
+  { "intlh.sn", TILEPRO_OPC_INTLH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "inv", TILE_OPC_INV, 0x2, 1, TREG_ZERO, 1,
+  { "inv", TILEPRO_OPC_INV, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "iret", TILE_OPC_IRET, 0x2, 0, TREG_ZERO, 1,
+  { "iret", TILEPRO_OPC_IRET, 0x2, 0, TREG_ZERO, 1,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "jalb", TILE_OPC_JALB, 0x2, 1, TREG_LR, 1,
+  { "jalb", TILEPRO_OPC_JALB, 0x2, 1, TREG_LR, 1,
     { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
   },
-  { "jalf", TILE_OPC_JALF, 0x2, 1, TREG_LR, 1,
+  { "jalf", TILEPRO_OPC_JALF, 0x2, 1, TREG_LR, 1,
     { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
   },
-  { "jalr", TILE_OPC_JALR, 0x2, 1, TREG_LR, 1,
+  { "jalr", TILEPRO_OPC_JALR, 0x2, 1, TREG_LR, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "jalrp", TILE_OPC_JALRP, 0x2, 1, TREG_LR, 1,
+  { "jalrp", TILEPRO_OPC_JALRP, 0x2, 1, TREG_LR, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "jb", TILE_OPC_JB, 0x2, 1, TREG_ZERO, 1,
+  { "jb", TILEPRO_OPC_JB, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
   },
-  { "jf", TILE_OPC_JF, 0x2, 1, TREG_ZERO, 1,
+  { "jf", TILEPRO_OPC_JF, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
   },
-  { "jr", TILE_OPC_JR, 0x2, 1, TREG_ZERO, 1,
+  { "jr", TILEPRO_OPC_JR, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "jrp", TILE_OPC_JRP, 0x2, 1, TREG_ZERO, 1,
+  { "jrp", TILEPRO_OPC_JRP, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lb", TILE_OPC_LB, 0x12, 2, TREG_ZERO, 1,
+  { "lb", TILEPRO_OPC_LB, 0x12, 2, TREG_ZERO, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
   },
-  { "lb.sn", TILE_OPC_LB_SN, 0x2, 2, TREG_SN, 1,
+  { "lb.sn", TILEPRO_OPC_LB_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lb_u", TILE_OPC_LB_U, 0x12, 2, TREG_ZERO, 1,
+  { "lb_u", TILEPRO_OPC_LB_U, 0x12, 2, TREG_ZERO, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
   },
-  { "lb_u.sn", TILE_OPC_LB_U_SN, 0x2, 2, TREG_SN, 1,
+  { "lb_u.sn", TILEPRO_OPC_LB_U_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lbadd", TILE_OPC_LBADD, 0x2, 3, TREG_ZERO, 1,
+  { "lbadd", TILEPRO_OPC_LBADD, 0x2, 3, TREG_ZERO, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lbadd.sn", TILE_OPC_LBADD_SN, 0x2, 3, TREG_SN, 1,
+  { "lbadd.sn", TILEPRO_OPC_LBADD_SN, 0x2, 3, TREG_SN, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lbadd_u", TILE_OPC_LBADD_U, 0x2, 3, TREG_ZERO, 1,
+  { "lbadd_u", TILEPRO_OPC_LBADD_U, 0x2, 3, TREG_ZERO, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lbadd_u.sn", TILE_OPC_LBADD_U_SN, 0x2, 3, TREG_SN, 1,
+  { "lbadd_u.sn", TILEPRO_OPC_LBADD_U_SN, 0x2, 3, TREG_SN, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lh", TILE_OPC_LH, 0x12, 2, TREG_ZERO, 1,
+  { "lh", TILEPRO_OPC_LH, 0x12, 2, TREG_ZERO, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
   },
-  { "lh.sn", TILE_OPC_LH_SN, 0x2, 2, TREG_SN, 1,
+  { "lh.sn", TILEPRO_OPC_LH_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lh_u", TILE_OPC_LH_U, 0x12, 2, TREG_ZERO, 1,
+  { "lh_u", TILEPRO_OPC_LH_U, 0x12, 2, TREG_ZERO, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
   },
-  { "lh_u.sn", TILE_OPC_LH_U_SN, 0x2, 2, TREG_SN, 1,
+  { "lh_u.sn", TILEPRO_OPC_LH_U_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lhadd", TILE_OPC_LHADD, 0x2, 3, TREG_ZERO, 1,
+  { "lhadd", TILEPRO_OPC_LHADD, 0x2, 3, TREG_ZERO, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lhadd.sn", TILE_OPC_LHADD_SN, 0x2, 3, TREG_SN, 1,
+  { "lhadd.sn", TILEPRO_OPC_LHADD_SN, 0x2, 3, TREG_SN, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lhadd_u", TILE_OPC_LHADD_U, 0x2, 3, TREG_ZERO, 1,
+  { "lhadd_u", TILEPRO_OPC_LHADD_U, 0x2, 3, TREG_ZERO, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lhadd_u.sn", TILE_OPC_LHADD_U_SN, 0x2, 3, TREG_SN, 1,
+  { "lhadd_u.sn", TILEPRO_OPC_LHADD_U_SN, 0x2, 3, TREG_SN, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lnk", TILE_OPC_LNK, 0x2, 1, TREG_ZERO, 1,
+  { "lnk", TILEPRO_OPC_LNK, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lnk.sn", TILE_OPC_LNK_SN, 0x2, 1, TREG_SN, 1,
+  { "lnk.sn", TILEPRO_OPC_LNK_SN, 0x2, 1, TREG_SN, 1,
     { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lw", TILE_OPC_LW, 0x12, 2, TREG_ZERO, 1,
+  { "lw", TILEPRO_OPC_LW, 0x12, 2, TREG_ZERO, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
   },
-  { "lw.sn", TILE_OPC_LW_SN, 0x2, 2, TREG_SN, 1,
+  { "lw.sn", TILEPRO_OPC_LW_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lw_na", TILE_OPC_LW_NA, 0x2, 2, TREG_ZERO, 1,
+  { "lw_na", TILEPRO_OPC_LW_NA, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lw_na.sn", TILE_OPC_LW_NA_SN, 0x2, 2, TREG_SN, 1,
+  { "lw_na.sn", TILEPRO_OPC_LW_NA_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lwadd", TILE_OPC_LWADD, 0x2, 3, TREG_ZERO, 1,
+  { "lwadd", TILEPRO_OPC_LWADD, 0x2, 3, TREG_ZERO, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lwadd.sn", TILE_OPC_LWADD_SN, 0x2, 3, TREG_SN, 1,
+  { "lwadd.sn", TILEPRO_OPC_LWADD_SN, 0x2, 3, TREG_SN, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lwadd_na", TILE_OPC_LWADD_NA, 0x2, 3, TREG_ZERO, 1,
+  { "lwadd_na", TILEPRO_OPC_LWADD_NA, 0x2, 3, TREG_ZERO, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "lwadd_na.sn", TILE_OPC_LWADD_NA_SN, 0x2, 3, TREG_SN, 1,
+  { "lwadd_na.sn", TILEPRO_OPC_LWADD_NA_SN, 0x2, 3, TREG_SN, 1,
     { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "maxb_u", TILE_OPC_MAXB_U, 0x3, 3, TREG_ZERO, 1,
+  { "maxb_u", TILEPRO_OPC_MAXB_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "maxb_u.sn", TILE_OPC_MAXB_U_SN, 0x3, 3, TREG_SN, 1,
+  { "maxb_u.sn", TILEPRO_OPC_MAXB_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "maxh", TILE_OPC_MAXH, 0x3, 3, TREG_ZERO, 1,
+  { "maxh", TILEPRO_OPC_MAXH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "maxh.sn", TILE_OPC_MAXH_SN, 0x3, 3, TREG_SN, 1,
+  { "maxh.sn", TILEPRO_OPC_MAXH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "maxib_u", TILE_OPC_MAXIB_U, 0x3, 3, TREG_ZERO, 1,
+  { "maxib_u", TILEPRO_OPC_MAXIB_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "maxib_u.sn", TILE_OPC_MAXIB_U_SN, 0x3, 3, TREG_SN, 1,
+  { "maxib_u.sn", TILEPRO_OPC_MAXIB_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "maxih", TILE_OPC_MAXIH, 0x3, 3, TREG_ZERO, 1,
+  { "maxih", TILEPRO_OPC_MAXIH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "maxih.sn", TILE_OPC_MAXIH_SN, 0x3, 3, TREG_SN, 1,
+  { "maxih.sn", TILEPRO_OPC_MAXIH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mf", TILE_OPC_MF, 0x2, 0, TREG_ZERO, 1,
+  { "mf", TILEPRO_OPC_MF, 0x2, 0, TREG_ZERO, 1,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "mfspr", TILE_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,
+  { "mfspr", TILEPRO_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 9, 25 }, { 0, }, { 0, }, { 0, } },
   },
-  { "minb_u", TILE_OPC_MINB_U, 0x3, 3, TREG_ZERO, 1,
+  { "minb_u", TILEPRO_OPC_MINB_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "minb_u.sn", TILE_OPC_MINB_U_SN, 0x3, 3, TREG_SN, 1,
+  { "minb_u.sn", TILEPRO_OPC_MINB_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "minh", TILE_OPC_MINH, 0x3, 3, TREG_ZERO, 1,
+  { "minh", TILEPRO_OPC_MINH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "minh.sn", TILE_OPC_MINH_SN, 0x3, 3, TREG_SN, 1,
+  { "minh.sn", TILEPRO_OPC_MINH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "minib_u", TILE_OPC_MINIB_U, 0x3, 3, TREG_ZERO, 1,
+  { "minib_u", TILEPRO_OPC_MINIB_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "minib_u.sn", TILE_OPC_MINIB_U_SN, 0x3, 3, TREG_SN, 1,
+  { "minib_u.sn", TILEPRO_OPC_MINIB_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "minih", TILE_OPC_MINIH, 0x3, 3, TREG_ZERO, 1,
+  { "minih", TILEPRO_OPC_MINIH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "minih.sn", TILE_OPC_MINIH_SN, 0x3, 3, TREG_SN, 1,
+  { "minih.sn", TILEPRO_OPC_MINIH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mm", TILE_OPC_MM, 0x3, 5, TREG_ZERO, 1,
+  { "mm", TILEPRO_OPC_MM, 0x3, 5, TREG_ZERO, 1,
     { { 7, 8, 16, 26, 27 }, { 9, 10, 17, 28, 29 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mnz", TILE_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,
+  { "mnz", TILEPRO_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "mnz.sn", TILE_OPC_MNZ_SN, 0x3, 3, TREG_SN, 1,
+  { "mnz.sn", TILEPRO_OPC_MNZ_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mnzb", TILE_OPC_MNZB, 0x3, 3, TREG_ZERO, 1,
+  { "mnzb", TILEPRO_OPC_MNZB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mnzb.sn", TILE_OPC_MNZB_SN, 0x3, 3, TREG_SN, 1,
+  { "mnzb.sn", TILEPRO_OPC_MNZB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mnzh", TILE_OPC_MNZH, 0x3, 3, TREG_ZERO, 1,
+  { "mnzh", TILEPRO_OPC_MNZH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mnzh.sn", TILE_OPC_MNZH_SN, 0x3, 3, TREG_SN, 1,
+  { "mnzh.sn", TILEPRO_OPC_MNZH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mtspr", TILE_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,
+  { "mtspr", TILEPRO_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 30, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhh_ss", TILE_OPC_MULHH_SS, 0x5, 3, TREG_ZERO, 1,
+  { "mulhh_ss", TILEPRO_OPC_MULHH_SS, 0x5, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mulhh_ss.sn", TILE_OPC_MULHH_SS_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhh_ss.sn", TILEPRO_OPC_MULHH_SS_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhh_su", TILE_OPC_MULHH_SU, 0x1, 3, TREG_ZERO, 1,
+  { "mulhh_su", TILEPRO_OPC_MULHH_SU, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhh_su.sn", TILE_OPC_MULHH_SU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhh_su.sn", TILEPRO_OPC_MULHH_SU_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhh_uu", TILE_OPC_MULHH_UU, 0x5, 3, TREG_ZERO, 1,
+  { "mulhh_uu", TILEPRO_OPC_MULHH_UU, 0x5, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mulhh_uu.sn", TILE_OPC_MULHH_UU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhh_uu.sn", TILEPRO_OPC_MULHH_UU_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhha_ss", TILE_OPC_MULHHA_SS, 0x5, 3, TREG_ZERO, 1,
+  { "mulhha_ss", TILEPRO_OPC_MULHHA_SS, 0x5, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mulhha_ss.sn", TILE_OPC_MULHHA_SS_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhha_ss.sn", TILEPRO_OPC_MULHHA_SS_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhha_su", TILE_OPC_MULHHA_SU, 0x1, 3, TREG_ZERO, 1,
+  { "mulhha_su", TILEPRO_OPC_MULHHA_SU, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhha_su.sn", TILE_OPC_MULHHA_SU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhha_su.sn", TILEPRO_OPC_MULHHA_SU_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhha_uu", TILE_OPC_MULHHA_UU, 0x5, 3, TREG_ZERO, 1,
+  { "mulhha_uu", TILEPRO_OPC_MULHHA_UU, 0x5, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mulhha_uu.sn", TILE_OPC_MULHHA_UU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhha_uu.sn", TILEPRO_OPC_MULHHA_UU_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhhsa_uu", TILE_OPC_MULHHSA_UU, 0x1, 3, TREG_ZERO, 1,
+  { "mulhhsa_uu", TILEPRO_OPC_MULHHSA_UU, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhhsa_uu.sn", TILE_OPC_MULHHSA_UU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhhsa_uu.sn", TILEPRO_OPC_MULHHSA_UU_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhl_ss", TILE_OPC_MULHL_SS, 0x1, 3, TREG_ZERO, 1,
+  { "mulhl_ss", TILEPRO_OPC_MULHL_SS, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhl_ss.sn", TILE_OPC_MULHL_SS_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhl_ss.sn", TILEPRO_OPC_MULHL_SS_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhl_su", TILE_OPC_MULHL_SU, 0x1, 3, TREG_ZERO, 1,
+  { "mulhl_su", TILEPRO_OPC_MULHL_SU, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhl_su.sn", TILE_OPC_MULHL_SU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhl_su.sn", TILEPRO_OPC_MULHL_SU_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhl_us", TILE_OPC_MULHL_US, 0x1, 3, TREG_ZERO, 1,
+  { "mulhl_us", TILEPRO_OPC_MULHL_US, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhl_us.sn", TILE_OPC_MULHL_US_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhl_us.sn", TILEPRO_OPC_MULHL_US_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhl_uu", TILE_OPC_MULHL_UU, 0x1, 3, TREG_ZERO, 1,
+  { "mulhl_uu", TILEPRO_OPC_MULHL_UU, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhl_uu.sn", TILE_OPC_MULHL_UU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhl_uu.sn", TILEPRO_OPC_MULHL_UU_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhla_ss", TILE_OPC_MULHLA_SS, 0x1, 3, TREG_ZERO, 1,
+  { "mulhla_ss", TILEPRO_OPC_MULHLA_SS, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhla_ss.sn", TILE_OPC_MULHLA_SS_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhla_ss.sn", TILEPRO_OPC_MULHLA_SS_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhla_su", TILE_OPC_MULHLA_SU, 0x1, 3, TREG_ZERO, 1,
+  { "mulhla_su", TILEPRO_OPC_MULHLA_SU, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhla_su.sn", TILE_OPC_MULHLA_SU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhla_su.sn", TILEPRO_OPC_MULHLA_SU_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhla_us", TILE_OPC_MULHLA_US, 0x1, 3, TREG_ZERO, 1,
+  { "mulhla_us", TILEPRO_OPC_MULHLA_US, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhla_us.sn", TILE_OPC_MULHLA_US_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhla_us.sn", TILEPRO_OPC_MULHLA_US_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhla_uu", TILE_OPC_MULHLA_UU, 0x1, 3, TREG_ZERO, 1,
+  { "mulhla_uu", TILEPRO_OPC_MULHLA_UU, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhla_uu.sn", TILE_OPC_MULHLA_UU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhla_uu.sn", TILEPRO_OPC_MULHLA_UU_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulhlsa_uu", TILE_OPC_MULHLSA_UU, 0x5, 3, TREG_ZERO, 1,
+  { "mulhlsa_uu", TILEPRO_OPC_MULHLSA_UU, 0x5, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mulhlsa_uu.sn", TILE_OPC_MULHLSA_UU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulhlsa_uu.sn", TILEPRO_OPC_MULHLSA_UU_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulll_ss", TILE_OPC_MULLL_SS, 0x5, 3, TREG_ZERO, 1,
+  { "mulll_ss", TILEPRO_OPC_MULLL_SS, 0x5, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mulll_ss.sn", TILE_OPC_MULLL_SS_SN, 0x1, 3, TREG_SN, 1,
+  { "mulll_ss.sn", TILEPRO_OPC_MULLL_SS_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulll_su", TILE_OPC_MULLL_SU, 0x1, 3, TREG_ZERO, 1,
+  { "mulll_su", TILEPRO_OPC_MULLL_SU, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulll_su.sn", TILE_OPC_MULLL_SU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulll_su.sn", TILEPRO_OPC_MULLL_SU_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulll_uu", TILE_OPC_MULLL_UU, 0x5, 3, TREG_ZERO, 1,
+  { "mulll_uu", TILEPRO_OPC_MULLL_UU, 0x5, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mulll_uu.sn", TILE_OPC_MULLL_UU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulll_uu.sn", TILEPRO_OPC_MULLL_UU_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mullla_ss", TILE_OPC_MULLLA_SS, 0x5, 3, TREG_ZERO, 1,
+  { "mullla_ss", TILEPRO_OPC_MULLLA_SS, 0x5, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mullla_ss.sn", TILE_OPC_MULLLA_SS_SN, 0x1, 3, TREG_SN, 1,
+  { "mullla_ss.sn", TILEPRO_OPC_MULLLA_SS_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mullla_su", TILE_OPC_MULLLA_SU, 0x1, 3, TREG_ZERO, 1,
+  { "mullla_su", TILEPRO_OPC_MULLLA_SU, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mullla_su.sn", TILE_OPC_MULLLA_SU_SN, 0x1, 3, TREG_SN, 1,
+  { "mullla_su.sn", TILEPRO_OPC_MULLLA_SU_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mullla_uu", TILE_OPC_MULLLA_UU, 0x5, 3, TREG_ZERO, 1,
+  { "mullla_uu", TILEPRO_OPC_MULLLA_UU, 0x5, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mullla_uu.sn", TILE_OPC_MULLLA_UU_SN, 0x1, 3, TREG_SN, 1,
+  { "mullla_uu.sn", TILEPRO_OPC_MULLLA_UU_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulllsa_uu", TILE_OPC_MULLLSA_UU, 0x1, 3, TREG_ZERO, 1,
+  { "mulllsa_uu", TILEPRO_OPC_MULLLSA_UU, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mulllsa_uu.sn", TILE_OPC_MULLLSA_UU_SN, 0x1, 3, TREG_SN, 1,
+  { "mulllsa_uu.sn", TILEPRO_OPC_MULLLSA_UU_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mvnz", TILE_OPC_MVNZ, 0x5, 3, TREG_ZERO, 1,
+  { "mvnz", TILEPRO_OPC_MVNZ, 0x5, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mvnz.sn", TILE_OPC_MVNZ_SN, 0x1, 3, TREG_SN, 1,
+  { "mvnz.sn", TILEPRO_OPC_MVNZ_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mvz", TILE_OPC_MVZ, 0x5, 3, TREG_ZERO, 1,
+  { "mvz", TILEPRO_OPC_MVZ, 0x5, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
   },
-  { "mvz.sn", TILE_OPC_MVZ_SN, 0x1, 3, TREG_SN, 1,
+  { "mvz.sn", TILEPRO_OPC_MVZ_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "mz", TILE_OPC_MZ, 0xf, 3, TREG_ZERO, 1,
+  { "mz", TILEPRO_OPC_MZ, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "mz.sn", TILE_OPC_MZ_SN, 0x3, 3, TREG_SN, 1,
+  { "mz.sn", TILEPRO_OPC_MZ_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mzb", TILE_OPC_MZB, 0x3, 3, TREG_ZERO, 1,
+  { "mzb", TILEPRO_OPC_MZB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mzb.sn", TILE_OPC_MZB_SN, 0x3, 3, TREG_SN, 1,
+  { "mzb.sn", TILEPRO_OPC_MZB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mzh", TILE_OPC_MZH, 0x3, 3, TREG_ZERO, 1,
+  { "mzh", TILEPRO_OPC_MZH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "mzh.sn", TILE_OPC_MZH_SN, 0x3, 3, TREG_SN, 1,
+  { "mzh.sn", TILEPRO_OPC_MZH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "nap", TILE_OPC_NAP, 0x2, 0, TREG_ZERO, 0,
+  { "nap", TILEPRO_OPC_NAP, 0x2, 0, TREG_ZERO, 0,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "nop", TILE_OPC_NOP, 0xf, 0, TREG_ZERO, 1,
+  { "nop", TILEPRO_OPC_NOP, 0xf, 0, TREG_ZERO, 1,
     { {  }, {  }, {  }, {  }, { 0, } },
   },
-  { "nor", TILE_OPC_NOR, 0xf, 3, TREG_ZERO, 1,
+  { "nor", TILEPRO_OPC_NOR, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "nor.sn", TILE_OPC_NOR_SN, 0x3, 3, TREG_SN, 1,
+  { "nor.sn", TILEPRO_OPC_NOR_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "or", TILE_OPC_OR, 0xf, 3, TREG_ZERO, 1,
+  { "or", TILEPRO_OPC_OR, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "or.sn", TILE_OPC_OR_SN, 0x3, 3, TREG_SN, 1,
+  { "or.sn", TILEPRO_OPC_OR_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "ori", TILE_OPC_ORI, 0xf, 3, TREG_ZERO, 1,
+  { "ori", TILEPRO_OPC_ORI, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
   },
-  { "ori.sn", TILE_OPC_ORI_SN, 0x3, 3, TREG_SN, 1,
+  { "ori.sn", TILEPRO_OPC_ORI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "packbs_u", TILE_OPC_PACKBS_U, 0x3, 3, TREG_ZERO, 1,
+  { "packbs_u", TILEPRO_OPC_PACKBS_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "packbs_u.sn", TILE_OPC_PACKBS_U_SN, 0x3, 3, TREG_SN, 1,
+  { "packbs_u.sn", TILEPRO_OPC_PACKBS_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "packhb", TILE_OPC_PACKHB, 0x3, 3, TREG_ZERO, 1,
+  { "packhb", TILEPRO_OPC_PACKHB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "packhb.sn", TILE_OPC_PACKHB_SN, 0x3, 3, TREG_SN, 1,
+  { "packhb.sn", TILEPRO_OPC_PACKHB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "packhs", TILE_OPC_PACKHS, 0x3, 3, TREG_ZERO, 1,
+  { "packhs", TILEPRO_OPC_PACKHS, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "packhs.sn", TILE_OPC_PACKHS_SN, 0x3, 3, TREG_SN, 1,
+  { "packhs.sn", TILEPRO_OPC_PACKHS_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "packlb", TILE_OPC_PACKLB, 0x3, 3, TREG_ZERO, 1,
+  { "packlb", TILEPRO_OPC_PACKLB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "packlb.sn", TILE_OPC_PACKLB_SN, 0x3, 3, TREG_SN, 1,
+  { "packlb.sn", TILEPRO_OPC_PACKLB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "pcnt", TILE_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,
+  { "pcnt", TILEPRO_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,
     { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
   },
-  { "pcnt.sn", TILE_OPC_PCNT_SN, 0x1, 2, TREG_SN, 1,
+  { "pcnt.sn", TILEPRO_OPC_PCNT_SN, 0x1, 2, TREG_SN, 1,
     { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "rl", TILE_OPC_RL, 0xf, 3, TREG_ZERO, 1,
+  { "rl", TILEPRO_OPC_RL, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "rl.sn", TILE_OPC_RL_SN, 0x3, 3, TREG_SN, 1,
+  { "rl.sn", TILEPRO_OPC_RL_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "rli", TILE_OPC_RLI, 0xf, 3, TREG_ZERO, 1,
+  { "rli", TILEPRO_OPC_RLI, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
   },
-  { "rli.sn", TILE_OPC_RLI_SN, 0x3, 3, TREG_SN, 1,
+  { "rli.sn", TILEPRO_OPC_RLI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "s1a", TILE_OPC_S1A, 0xf, 3, TREG_ZERO, 1,
+  { "s1a", TILEPRO_OPC_S1A, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "s1a.sn", TILE_OPC_S1A_SN, 0x3, 3, TREG_SN, 1,
+  { "s1a.sn", TILEPRO_OPC_S1A_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "s2a", TILE_OPC_S2A, 0xf, 3, TREG_ZERO, 1,
+  { "s2a", TILEPRO_OPC_S2A, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "s2a.sn", TILE_OPC_S2A_SN, 0x3, 3, TREG_SN, 1,
+  { "s2a.sn", TILEPRO_OPC_S2A_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "s3a", TILE_OPC_S3A, 0xf, 3, TREG_ZERO, 1,
+  { "s3a", TILEPRO_OPC_S3A, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "s3a.sn", TILE_OPC_S3A_SN, 0x3, 3, TREG_SN, 1,
+  { "s3a.sn", TILEPRO_OPC_S3A_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadab_u", TILE_OPC_SADAB_U, 0x1, 3, TREG_ZERO, 1,
+  { "sadab_u", TILEPRO_OPC_SADAB_U, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadab_u.sn", TILE_OPC_SADAB_U_SN, 0x1, 3, TREG_SN, 1,
+  { "sadab_u.sn", TILEPRO_OPC_SADAB_U_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadah", TILE_OPC_SADAH, 0x1, 3, TREG_ZERO, 1,
+  { "sadah", TILEPRO_OPC_SADAH, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadah.sn", TILE_OPC_SADAH_SN, 0x1, 3, TREG_SN, 1,
+  { "sadah.sn", TILEPRO_OPC_SADAH_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadah_u", TILE_OPC_SADAH_U, 0x1, 3, TREG_ZERO, 1,
+  { "sadah_u", TILEPRO_OPC_SADAH_U, 0x1, 3, TREG_ZERO, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadah_u.sn", TILE_OPC_SADAH_U_SN, 0x1, 3, TREG_SN, 1,
+  { "sadah_u.sn", TILEPRO_OPC_SADAH_U_SN, 0x1, 3, TREG_SN, 1,
     { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadb_u", TILE_OPC_SADB_U, 0x1, 3, TREG_ZERO, 1,
+  { "sadb_u", TILEPRO_OPC_SADB_U, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadb_u.sn", TILE_OPC_SADB_U_SN, 0x1, 3, TREG_SN, 1,
+  { "sadb_u.sn", TILEPRO_OPC_SADB_U_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadh", TILE_OPC_SADH, 0x1, 3, TREG_ZERO, 1,
+  { "sadh", TILEPRO_OPC_SADH, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadh.sn", TILE_OPC_SADH_SN, 0x1, 3, TREG_SN, 1,
+  { "sadh.sn", TILEPRO_OPC_SADH_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadh_u", TILE_OPC_SADH_U, 0x1, 3, TREG_ZERO, 1,
+  { "sadh_u", TILEPRO_OPC_SADH_U, 0x1, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sadh_u.sn", TILE_OPC_SADH_U_SN, 0x1, 3, TREG_SN, 1,
+  { "sadh_u.sn", TILEPRO_OPC_SADH_U_SN, 0x1, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "sb", TILE_OPC_SB, 0x12, 2, TREG_ZERO, 1,
+  { "sb", TILEPRO_OPC_SB, 0x12, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
   },
-  { "sbadd", TILE_OPC_SBADD, 0x2, 3, TREG_ZERO, 1,
+  { "sbadd", TILEPRO_OPC_SBADD, 0x2, 3, TREG_ZERO, 1,
     { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seq", TILE_OPC_SEQ, 0xf, 3, TREG_ZERO, 1,
+  { "seq", TILEPRO_OPC_SEQ, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "seq.sn", TILE_OPC_SEQ_SN, 0x3, 3, TREG_SN, 1,
+  { "seq.sn", TILEPRO_OPC_SEQ_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seqb", TILE_OPC_SEQB, 0x3, 3, TREG_ZERO, 1,
+  { "seqb", TILEPRO_OPC_SEQB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seqb.sn", TILE_OPC_SEQB_SN, 0x3, 3, TREG_SN, 1,
+  { "seqb.sn", TILEPRO_OPC_SEQB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seqh", TILE_OPC_SEQH, 0x3, 3, TREG_ZERO, 1,
+  { "seqh", TILEPRO_OPC_SEQH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seqh.sn", TILE_OPC_SEQH_SN, 0x3, 3, TREG_SN, 1,
+  { "seqh.sn", TILEPRO_OPC_SEQH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seqi", TILE_OPC_SEQI, 0xf, 3, TREG_ZERO, 1,
+  { "seqi", TILEPRO_OPC_SEQI, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
   },
-  { "seqi.sn", TILE_OPC_SEQI_SN, 0x3, 3, TREG_SN, 1,
+  { "seqi.sn", TILEPRO_OPC_SEQI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seqib", TILE_OPC_SEQIB, 0x3, 3, TREG_ZERO, 1,
+  { "seqib", TILEPRO_OPC_SEQIB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seqib.sn", TILE_OPC_SEQIB_SN, 0x3, 3, TREG_SN, 1,
+  { "seqib.sn", TILEPRO_OPC_SEQIB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seqih", TILE_OPC_SEQIH, 0x3, 3, TREG_ZERO, 1,
+  { "seqih", TILEPRO_OPC_SEQIH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "seqih.sn", TILE_OPC_SEQIH_SN, 0x3, 3, TREG_SN, 1,
+  { "seqih.sn", TILEPRO_OPC_SEQIH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sh", TILE_OPC_SH, 0x12, 2, TREG_ZERO, 1,
+  { "sh", TILEPRO_OPC_SH, 0x12, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
   },
-  { "shadd", TILE_OPC_SHADD, 0x2, 3, TREG_ZERO, 1,
+  { "shadd", TILEPRO_OPC_SHADD, 0x2, 3, TREG_ZERO, 1,
     { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shl", TILE_OPC_SHL, 0xf, 3, TREG_ZERO, 1,
+  { "shl", TILEPRO_OPC_SHL, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "shl.sn", TILE_OPC_SHL_SN, 0x3, 3, TREG_SN, 1,
+  { "shl.sn", TILEPRO_OPC_SHL_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shlb", TILE_OPC_SHLB, 0x3, 3, TREG_ZERO, 1,
+  { "shlb", TILEPRO_OPC_SHLB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shlb.sn", TILE_OPC_SHLB_SN, 0x3, 3, TREG_SN, 1,
+  { "shlb.sn", TILEPRO_OPC_SHLB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shlh", TILE_OPC_SHLH, 0x3, 3, TREG_ZERO, 1,
+  { "shlh", TILEPRO_OPC_SHLH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shlh.sn", TILE_OPC_SHLH_SN, 0x3, 3, TREG_SN, 1,
+  { "shlh.sn", TILEPRO_OPC_SHLH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shli", TILE_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,
+  { "shli", TILEPRO_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
   },
-  { "shli.sn", TILE_OPC_SHLI_SN, 0x3, 3, TREG_SN, 1,
+  { "shli.sn", TILEPRO_OPC_SHLI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shlib", TILE_OPC_SHLIB, 0x3, 3, TREG_ZERO, 1,
+  { "shlib", TILEPRO_OPC_SHLIB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shlib.sn", TILE_OPC_SHLIB_SN, 0x3, 3, TREG_SN, 1,
+  { "shlib.sn", TILEPRO_OPC_SHLIB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shlih", TILE_OPC_SHLIH, 0x3, 3, TREG_ZERO, 1,
+  { "shlih", TILEPRO_OPC_SHLIH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shlih.sn", TILE_OPC_SHLIH_SN, 0x3, 3, TREG_SN, 1,
+  { "shlih.sn", TILEPRO_OPC_SHLIH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shr", TILE_OPC_SHR, 0xf, 3, TREG_ZERO, 1,
+  { "shr", TILEPRO_OPC_SHR, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "shr.sn", TILE_OPC_SHR_SN, 0x3, 3, TREG_SN, 1,
+  { "shr.sn", TILEPRO_OPC_SHR_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shrb", TILE_OPC_SHRB, 0x3, 3, TREG_ZERO, 1,
+  { "shrb", TILEPRO_OPC_SHRB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shrb.sn", TILE_OPC_SHRB_SN, 0x3, 3, TREG_SN, 1,
+  { "shrb.sn", TILEPRO_OPC_SHRB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shrh", TILE_OPC_SHRH, 0x3, 3, TREG_ZERO, 1,
+  { "shrh", TILEPRO_OPC_SHRH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shrh.sn", TILE_OPC_SHRH_SN, 0x3, 3, TREG_SN, 1,
+  { "shrh.sn", TILEPRO_OPC_SHRH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shri", TILE_OPC_SHRI, 0xf, 3, TREG_ZERO, 1,
+  { "shri", TILEPRO_OPC_SHRI, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
   },
-  { "shri.sn", TILE_OPC_SHRI_SN, 0x3, 3, TREG_SN, 1,
+  { "shri.sn", TILEPRO_OPC_SHRI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shrib", TILE_OPC_SHRIB, 0x3, 3, TREG_ZERO, 1,
+  { "shrib", TILEPRO_OPC_SHRIB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shrib.sn", TILE_OPC_SHRIB_SN, 0x3, 3, TREG_SN, 1,
+  { "shrib.sn", TILEPRO_OPC_SHRIB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shrih", TILE_OPC_SHRIH, 0x3, 3, TREG_ZERO, 1,
+  { "shrih", TILEPRO_OPC_SHRIH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "shrih.sn", TILE_OPC_SHRIH_SN, 0x3, 3, TREG_SN, 1,
+  { "shrih.sn", TILEPRO_OPC_SHRIH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slt", TILE_OPC_SLT, 0xf, 3, TREG_ZERO, 1,
+  { "slt", TILEPRO_OPC_SLT, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "slt.sn", TILE_OPC_SLT_SN, 0x3, 3, TREG_SN, 1,
+  { "slt.sn", TILEPRO_OPC_SLT_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slt_u", TILE_OPC_SLT_U, 0xf, 3, TREG_ZERO, 1,
+  { "slt_u", TILEPRO_OPC_SLT_U, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "slt_u.sn", TILE_OPC_SLT_U_SN, 0x3, 3, TREG_SN, 1,
+  { "slt_u.sn", TILEPRO_OPC_SLT_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltb", TILE_OPC_SLTB, 0x3, 3, TREG_ZERO, 1,
+  { "sltb", TILEPRO_OPC_SLTB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltb.sn", TILE_OPC_SLTB_SN, 0x3, 3, TREG_SN, 1,
+  { "sltb.sn", TILEPRO_OPC_SLTB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltb_u", TILE_OPC_SLTB_U, 0x3, 3, TREG_ZERO, 1,
+  { "sltb_u", TILEPRO_OPC_SLTB_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltb_u.sn", TILE_OPC_SLTB_U_SN, 0x3, 3, TREG_SN, 1,
+  { "sltb_u.sn", TILEPRO_OPC_SLTB_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slte", TILE_OPC_SLTE, 0xf, 3, TREG_ZERO, 1,
+  { "slte", TILEPRO_OPC_SLTE, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "slte.sn", TILE_OPC_SLTE_SN, 0x3, 3, TREG_SN, 1,
+  { "slte.sn", TILEPRO_OPC_SLTE_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slte_u", TILE_OPC_SLTE_U, 0xf, 3, TREG_ZERO, 1,
+  { "slte_u", TILEPRO_OPC_SLTE_U, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "slte_u.sn", TILE_OPC_SLTE_U_SN, 0x3, 3, TREG_SN, 1,
+  { "slte_u.sn", TILEPRO_OPC_SLTE_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slteb", TILE_OPC_SLTEB, 0x3, 3, TREG_ZERO, 1,
+  { "slteb", TILEPRO_OPC_SLTEB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slteb.sn", TILE_OPC_SLTEB_SN, 0x3, 3, TREG_SN, 1,
+  { "slteb.sn", TILEPRO_OPC_SLTEB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slteb_u", TILE_OPC_SLTEB_U, 0x3, 3, TREG_ZERO, 1,
+  { "slteb_u", TILEPRO_OPC_SLTEB_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slteb_u.sn", TILE_OPC_SLTEB_U_SN, 0x3, 3, TREG_SN, 1,
+  { "slteb_u.sn", TILEPRO_OPC_SLTEB_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slteh", TILE_OPC_SLTEH, 0x3, 3, TREG_ZERO, 1,
+  { "slteh", TILEPRO_OPC_SLTEH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slteh.sn", TILE_OPC_SLTEH_SN, 0x3, 3, TREG_SN, 1,
+  { "slteh.sn", TILEPRO_OPC_SLTEH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slteh_u", TILE_OPC_SLTEH_U, 0x3, 3, TREG_ZERO, 1,
+  { "slteh_u", TILEPRO_OPC_SLTEH_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slteh_u.sn", TILE_OPC_SLTEH_U_SN, 0x3, 3, TREG_SN, 1,
+  { "slteh_u.sn", TILEPRO_OPC_SLTEH_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slth", TILE_OPC_SLTH, 0x3, 3, TREG_ZERO, 1,
+  { "slth", TILEPRO_OPC_SLTH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slth.sn", TILE_OPC_SLTH_SN, 0x3, 3, TREG_SN, 1,
+  { "slth.sn", TILEPRO_OPC_SLTH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slth_u", TILE_OPC_SLTH_U, 0x3, 3, TREG_ZERO, 1,
+  { "slth_u", TILEPRO_OPC_SLTH_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slth_u.sn", TILE_OPC_SLTH_U_SN, 0x3, 3, TREG_SN, 1,
+  { "slth_u.sn", TILEPRO_OPC_SLTH_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slti", TILE_OPC_SLTI, 0xf, 3, TREG_ZERO, 1,
+  { "slti", TILEPRO_OPC_SLTI, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
   },
-  { "slti.sn", TILE_OPC_SLTI_SN, 0x3, 3, TREG_SN, 1,
+  { "slti.sn", TILEPRO_OPC_SLTI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "slti_u", TILE_OPC_SLTI_U, 0xf, 3, TREG_ZERO, 1,
+  { "slti_u", TILEPRO_OPC_SLTI_U, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
   },
-  { "slti_u.sn", TILE_OPC_SLTI_U_SN, 0x3, 3, TREG_SN, 1,
+  { "slti_u.sn", TILEPRO_OPC_SLTI_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltib", TILE_OPC_SLTIB, 0x3, 3, TREG_ZERO, 1,
+  { "sltib", TILEPRO_OPC_SLTIB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltib.sn", TILE_OPC_SLTIB_SN, 0x3, 3, TREG_SN, 1,
+  { "sltib.sn", TILEPRO_OPC_SLTIB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltib_u", TILE_OPC_SLTIB_U, 0x3, 3, TREG_ZERO, 1,
+  { "sltib_u", TILEPRO_OPC_SLTIB_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltib_u.sn", TILE_OPC_SLTIB_U_SN, 0x3, 3, TREG_SN, 1,
+  { "sltib_u.sn", TILEPRO_OPC_SLTIB_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltih", TILE_OPC_SLTIH, 0x3, 3, TREG_ZERO, 1,
+  { "sltih", TILEPRO_OPC_SLTIH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltih.sn", TILE_OPC_SLTIH_SN, 0x3, 3, TREG_SN, 1,
+  { "sltih.sn", TILEPRO_OPC_SLTIH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltih_u", TILE_OPC_SLTIH_U, 0x3, 3, TREG_ZERO, 1,
+  { "sltih_u", TILEPRO_OPC_SLTIH_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sltih_u.sn", TILE_OPC_SLTIH_U_SN, 0x3, 3, TREG_SN, 1,
+  { "sltih_u.sn", TILEPRO_OPC_SLTIH_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sne", TILE_OPC_SNE, 0xf, 3, TREG_ZERO, 1,
+  { "sne", TILEPRO_OPC_SNE, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "sne.sn", TILE_OPC_SNE_SN, 0x3, 3, TREG_SN, 1,
+  { "sne.sn", TILEPRO_OPC_SNE_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sneb", TILE_OPC_SNEB, 0x3, 3, TREG_ZERO, 1,
+  { "sneb", TILEPRO_OPC_SNEB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sneb.sn", TILE_OPC_SNEB_SN, 0x3, 3, TREG_SN, 1,
+  { "sneb.sn", TILEPRO_OPC_SNEB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sneh", TILE_OPC_SNEH, 0x3, 3, TREG_ZERO, 1,
+  { "sneh", TILEPRO_OPC_SNEH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sneh.sn", TILE_OPC_SNEH_SN, 0x3, 3, TREG_SN, 1,
+  { "sneh.sn", TILEPRO_OPC_SNEH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sra", TILE_OPC_SRA, 0xf, 3, TREG_ZERO, 1,
+  { "sra", TILEPRO_OPC_SRA, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "sra.sn", TILE_OPC_SRA_SN, 0x3, 3, TREG_SN, 1,
+  { "sra.sn", TILEPRO_OPC_SRA_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "srab", TILE_OPC_SRAB, 0x3, 3, TREG_ZERO, 1,
+  { "srab", TILEPRO_OPC_SRAB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "srab.sn", TILE_OPC_SRAB_SN, 0x3, 3, TREG_SN, 1,
+  { "srab.sn", TILEPRO_OPC_SRAB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "srah", TILE_OPC_SRAH, 0x3, 3, TREG_ZERO, 1,
+  { "srah", TILEPRO_OPC_SRAH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "srah.sn", TILE_OPC_SRAH_SN, 0x3, 3, TREG_SN, 1,
+  { "srah.sn", TILEPRO_OPC_SRAH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "srai", TILE_OPC_SRAI, 0xf, 3, TREG_ZERO, 1,
+  { "srai", TILEPRO_OPC_SRAI, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
   },
-  { "srai.sn", TILE_OPC_SRAI_SN, 0x3, 3, TREG_SN, 1,
+  { "srai.sn", TILEPRO_OPC_SRAI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sraib", TILE_OPC_SRAIB, 0x3, 3, TREG_ZERO, 1,
+  { "sraib", TILEPRO_OPC_SRAIB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sraib.sn", TILE_OPC_SRAIB_SN, 0x3, 3, TREG_SN, 1,
+  { "sraib.sn", TILEPRO_OPC_SRAIB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sraih", TILE_OPC_SRAIH, 0x3, 3, TREG_ZERO, 1,
+  { "sraih", TILEPRO_OPC_SRAIH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sraih.sn", TILE_OPC_SRAIH_SN, 0x3, 3, TREG_SN, 1,
+  { "sraih.sn", TILEPRO_OPC_SRAIH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sub", TILE_OPC_SUB, 0xf, 3, TREG_ZERO, 1,
+  { "sub", TILEPRO_OPC_SUB, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "sub.sn", TILE_OPC_SUB_SN, 0x3, 3, TREG_SN, 1,
+  { "sub.sn", TILEPRO_OPC_SUB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subb", TILE_OPC_SUBB, 0x3, 3, TREG_ZERO, 1,
+  { "subb", TILEPRO_OPC_SUBB, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subb.sn", TILE_OPC_SUBB_SN, 0x3, 3, TREG_SN, 1,
+  { "subb.sn", TILEPRO_OPC_SUBB_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subbs_u", TILE_OPC_SUBBS_U, 0x3, 3, TREG_ZERO, 1,
+  { "subbs_u", TILEPRO_OPC_SUBBS_U, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subbs_u.sn", TILE_OPC_SUBBS_U_SN, 0x3, 3, TREG_SN, 1,
+  { "subbs_u.sn", TILEPRO_OPC_SUBBS_U_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subh", TILE_OPC_SUBH, 0x3, 3, TREG_ZERO, 1,
+  { "subh", TILEPRO_OPC_SUBH, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subh.sn", TILE_OPC_SUBH_SN, 0x3, 3, TREG_SN, 1,
+  { "subh.sn", TILEPRO_OPC_SUBH_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subhs", TILE_OPC_SUBHS, 0x3, 3, TREG_ZERO, 1,
+  { "subhs", TILEPRO_OPC_SUBHS, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subhs.sn", TILE_OPC_SUBHS_SN, 0x3, 3, TREG_SN, 1,
+  { "subhs.sn", TILEPRO_OPC_SUBHS_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subs", TILE_OPC_SUBS, 0x3, 3, TREG_ZERO, 1,
+  { "subs", TILEPRO_OPC_SUBS, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "subs.sn", TILE_OPC_SUBS_SN, 0x3, 3, TREG_SN, 1,
+  { "subs.sn", TILEPRO_OPC_SUBS_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "sw", TILE_OPC_SW, 0x12, 2, TREG_ZERO, 1,
+  { "sw", TILEPRO_OPC_SW, 0x12, 2, TREG_ZERO, 1,
     { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
   },
-  { "swadd", TILE_OPC_SWADD, 0x2, 3, TREG_ZERO, 1,
+  { "swadd", TILEPRO_OPC_SWADD, 0x2, 3, TREG_ZERO, 1,
     { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
   },
-  { "swint0", TILE_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,
+  { "swint0", TILEPRO_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "swint1", TILE_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,
+  { "swint1", TILEPRO_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "swint2", TILE_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,
+  { "swint2", TILEPRO_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "swint3", TILE_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,
+  { "swint3", TILEPRO_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,
     { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
   },
-  { "tblidxb0", TILE_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,
+  { "tblidxb0", TILEPRO_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,
     { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
   },
-  { "tblidxb0.sn", TILE_OPC_TBLIDXB0_SN, 0x1, 2, TREG_SN, 1,
+  { "tblidxb0.sn", TILEPRO_OPC_TBLIDXB0_SN, 0x1, 2, TREG_SN, 1,
     { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "tblidxb1", TILE_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,
+  { "tblidxb1", TILEPRO_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,
     { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
   },
-  { "tblidxb1.sn", TILE_OPC_TBLIDXB1_SN, 0x1, 2, TREG_SN, 1,
+  { "tblidxb1.sn", TILEPRO_OPC_TBLIDXB1_SN, 0x1, 2, TREG_SN, 1,
     { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "tblidxb2", TILE_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,
+  { "tblidxb2", TILEPRO_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,
     { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
   },
-  { "tblidxb2.sn", TILE_OPC_TBLIDXB2_SN, 0x1, 2, TREG_SN, 1,
+  { "tblidxb2.sn", TILEPRO_OPC_TBLIDXB2_SN, 0x1, 2, TREG_SN, 1,
     { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "tblidxb3", TILE_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,
+  { "tblidxb3", TILEPRO_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,
     { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
   },
-  { "tblidxb3.sn", TILE_OPC_TBLIDXB3_SN, 0x1, 2, TREG_SN, 1,
+  { "tblidxb3.sn", TILEPRO_OPC_TBLIDXB3_SN, 0x1, 2, TREG_SN, 1,
     { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
   },
-  { "tns", TILE_OPC_TNS, 0x2, 2, TREG_ZERO, 1,
+  { "tns", TILEPRO_OPC_TNS, 0x2, 2, TREG_ZERO, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "tns.sn", TILE_OPC_TNS_SN, 0x2, 2, TREG_SN, 1,
+  { "tns.sn", TILEPRO_OPC_TNS_SN, 0x2, 2, TREG_SN, 1,
     { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "wh64", TILE_OPC_WH64, 0x2, 1, TREG_ZERO, 1,
+  { "wh64", TILEPRO_OPC_WH64, 0x2, 1, TREG_ZERO, 1,
     { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
   },
-  { "xor", TILE_OPC_XOR, 0xf, 3, TREG_ZERO, 1,
+  { "xor", TILEPRO_OPC_XOR, 0xf, 3, TREG_ZERO, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
   },
-  { "xor.sn", TILE_OPC_XOR_SN, 0x3, 3, TREG_SN, 1,
+  { "xor.sn", TILEPRO_OPC_XOR_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
   },
-  { "xori", TILE_OPC_XORI, 0x3, 3, TREG_ZERO, 1,
+  { "xori", TILEPRO_OPC_XORI, 0x3, 3, TREG_ZERO, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { "xori.sn", TILE_OPC_XORI_SN, 0x3, 3, TREG_SN, 1,
+  { "xori.sn", TILEPRO_OPC_XORI_SN, 0x3, 3, TREG_SN, 1,
     { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
   },
-  { NULL, TILE_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },
+  { NULL, TILEPRO_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },
   }
 };
 #define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6))
-#define CHILD(array_index) (TILE_OPC_NONE + (array_index))
+#define CHILD(array_index) (TILEPRO_OPC_NONE + (array_index))
 
 static const unsigned short decode_X0_fsm[1153] =
 {
   BITFIELD(22, 9) /* index 0 */,
   CHILD(513), CHILD(530), CHILD(547), CHILD(564), CHILD(596), CHILD(613),
-  CHILD(630), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, CHILD(663), CHILD(680), CHILD(697), CHILD(714), CHILD(746),
-  CHILD(763), CHILD(780), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, CHILD(813), CHILD(813), CHILD(813),
+  CHILD(630), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(663), CHILD(680), CHILD(697),
+  CHILD(714), CHILD(746), CHILD(763), CHILD(780), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
   CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
   CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
@@ -1227,7 +1247,8 @@ static const unsigned short decode_X0_fsm[1153] =
   CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
   CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
   CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
-  CHILD(813), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+  CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(828), CHILD(828),
+  CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
   CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
   CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
   CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
@@ -1237,7 +1258,7 @@ static const unsigned short decode_X0_fsm[1153] =
   CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
   CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
   CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
-  CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(843),
+  CHILD(828), CHILD(828), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
   CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
   CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
   CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
@@ -1248,333 +1269,371 @@ static const unsigned short decode_X0_fsm[1153] =
   CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
   CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
   CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
-  CHILD(843), CHILD(843), CHILD(843), CHILD(873), CHILD(878), CHILD(883),
-  CHILD(903), CHILD(908), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(913),
-  CHILD(918), CHILD(923), CHILD(943), CHILD(948), TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, CHILD(953), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(988), TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, CHILD(993),
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, CHILD(1076), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  CHILD(873), CHILD(878), CHILD(883), CHILD(903), CHILD(908),
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(913),
+  CHILD(918), CHILD(923), CHILD(943), CHILD(948), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(953), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(988), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, CHILD(993), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(1076), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(18, 4) /* index 513 */,
-  TILE_OPC_NONE, TILE_OPC_ADDB, TILE_OPC_ADDH, TILE_OPC_ADD,
-  TILE_OPC_ADIFFB_U, TILE_OPC_ADIFFH, TILE_OPC_AND, TILE_OPC_AVGB_U,
-  TILE_OPC_AVGH, TILE_OPC_CRC32_32, TILE_OPC_CRC32_8, TILE_OPC_INTHB,
-  TILE_OPC_INTHH, TILE_OPC_INTLB, TILE_OPC_INTLH, TILE_OPC_MAXB_U,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_ADDB, TILEPRO_OPC_ADDH, TILEPRO_OPC_ADD,
+  TILEPRO_OPC_ADIFFB_U, TILEPRO_OPC_ADIFFH, TILEPRO_OPC_AND,
+  TILEPRO_OPC_AVGB_U, TILEPRO_OPC_AVGH, TILEPRO_OPC_CRC32_32,
+  TILEPRO_OPC_CRC32_8, TILEPRO_OPC_INTHB, TILEPRO_OPC_INTHH,
+  TILEPRO_OPC_INTLB, TILEPRO_OPC_INTLH, TILEPRO_OPC_MAXB_U,
   BITFIELD(18, 4) /* index 530 */,
-  TILE_OPC_MAXH, TILE_OPC_MINB_U, TILE_OPC_MINH, TILE_OPC_MNZB, TILE_OPC_MNZH,
-  TILE_OPC_MNZ, TILE_OPC_MULHHA_SS, TILE_OPC_MULHHA_SU, TILE_OPC_MULHHA_UU,
-  TILE_OPC_MULHHSA_UU, TILE_OPC_MULHH_SS, TILE_OPC_MULHH_SU,
-  TILE_OPC_MULHH_UU, TILE_OPC_MULHLA_SS, TILE_OPC_MULHLA_SU,
-  TILE_OPC_MULHLA_US,
+  TILEPRO_OPC_MAXH, TILEPRO_OPC_MINB_U, TILEPRO_OPC_MINH, TILEPRO_OPC_MNZB,
+  TILEPRO_OPC_MNZH, TILEPRO_OPC_MNZ, TILEPRO_OPC_MULHHA_SS,
+  TILEPRO_OPC_MULHHA_SU, TILEPRO_OPC_MULHHA_UU, TILEPRO_OPC_MULHHSA_UU,
+  TILEPRO_OPC_MULHH_SS, TILEPRO_OPC_MULHH_SU, TILEPRO_OPC_MULHH_UU,
+  TILEPRO_OPC_MULHLA_SS, TILEPRO_OPC_MULHLA_SU, TILEPRO_OPC_MULHLA_US,
   BITFIELD(18, 4) /* index 547 */,
-  TILE_OPC_MULHLA_UU, TILE_OPC_MULHLSA_UU, TILE_OPC_MULHL_SS,
-  TILE_OPC_MULHL_SU, TILE_OPC_MULHL_US, TILE_OPC_MULHL_UU, TILE_OPC_MULLLA_SS,
-  TILE_OPC_MULLLA_SU, TILE_OPC_MULLLA_UU, TILE_OPC_MULLLSA_UU,
-  TILE_OPC_MULLL_SS, TILE_OPC_MULLL_SU, TILE_OPC_MULLL_UU, TILE_OPC_MVNZ,
-  TILE_OPC_MVZ, TILE_OPC_MZB,
+  TILEPRO_OPC_MULHLA_UU, TILEPRO_OPC_MULHLSA_UU, TILEPRO_OPC_MULHL_SS,
+  TILEPRO_OPC_MULHL_SU, TILEPRO_OPC_MULHL_US, TILEPRO_OPC_MULHL_UU,
+  TILEPRO_OPC_MULLLA_SS, TILEPRO_OPC_MULLLA_SU, TILEPRO_OPC_MULLLA_UU,
+  TILEPRO_OPC_MULLLSA_UU, TILEPRO_OPC_MULLL_SS, TILEPRO_OPC_MULLL_SU,
+  TILEPRO_OPC_MULLL_UU, TILEPRO_OPC_MVNZ, TILEPRO_OPC_MVZ, TILEPRO_OPC_MZB,
   BITFIELD(18, 4) /* index 564 */,
-  TILE_OPC_MZH, TILE_OPC_MZ, TILE_OPC_NOR, CHILD(581), TILE_OPC_PACKHB,
-  TILE_OPC_PACKLB, TILE_OPC_RL, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_S3A,
-  TILE_OPC_SADAB_U, TILE_OPC_SADAH, TILE_OPC_SADAH_U, TILE_OPC_SADB_U,
-  TILE_OPC_SADH, TILE_OPC_SADH_U,
+  TILEPRO_OPC_MZH, TILEPRO_OPC_MZ, TILEPRO_OPC_NOR, CHILD(581),
+  TILEPRO_OPC_PACKHB, TILEPRO_OPC_PACKLB, TILEPRO_OPC_RL, TILEPRO_OPC_S1A,
+  TILEPRO_OPC_S2A, TILEPRO_OPC_S3A, TILEPRO_OPC_SADAB_U, TILEPRO_OPC_SADAH,
+  TILEPRO_OPC_SADAH_U, TILEPRO_OPC_SADB_U, TILEPRO_OPC_SADH,
+  TILEPRO_OPC_SADH_U,
   BITFIELD(12, 2) /* index 581 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(586),
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(586),
   BITFIELD(14, 2) /* index 586 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(591),
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(591),
   BITFIELD(16, 2) /* index 591 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_MOVE,
   BITFIELD(18, 4) /* index 596 */,
-  TILE_OPC_SEQB, TILE_OPC_SEQH, TILE_OPC_SEQ, TILE_OPC_SHLB, TILE_OPC_SHLH,
-  TILE_OPC_SHL, TILE_OPC_SHRB, TILE_OPC_SHRH, TILE_OPC_SHR, TILE_OPC_SLTB,
-  TILE_OPC_SLTB_U, TILE_OPC_SLTEB, TILE_OPC_SLTEB_U, TILE_OPC_SLTEH,
-  TILE_OPC_SLTEH_U, TILE_OPC_SLTE,
+  TILEPRO_OPC_SEQB, TILEPRO_OPC_SEQH, TILEPRO_OPC_SEQ, TILEPRO_OPC_SHLB,
+  TILEPRO_OPC_SHLH, TILEPRO_OPC_SHL, TILEPRO_OPC_SHRB, TILEPRO_OPC_SHRH,
+  TILEPRO_OPC_SHR, TILEPRO_OPC_SLTB, TILEPRO_OPC_SLTB_U, TILEPRO_OPC_SLTEB,
+  TILEPRO_OPC_SLTEB_U, TILEPRO_OPC_SLTEH, TILEPRO_OPC_SLTEH_U,
+  TILEPRO_OPC_SLTE,
   BITFIELD(18, 4) /* index 613 */,
-  TILE_OPC_SLTE_U, TILE_OPC_SLTH, TILE_OPC_SLTH_U, TILE_OPC_SLT,
-  TILE_OPC_SLT_U, TILE_OPC_SNEB, TILE_OPC_SNEH, TILE_OPC_SNE, TILE_OPC_SRAB,
-  TILE_OPC_SRAH, TILE_OPC_SRA, TILE_OPC_SUBB, TILE_OPC_SUBH, TILE_OPC_SUB,
-  TILE_OPC_XOR, TILE_OPC_DWORD_ALIGN,
+  TILEPRO_OPC_SLTE_U, TILEPRO_OPC_SLTH, TILEPRO_OPC_SLTH_U, TILEPRO_OPC_SLT,
+  TILEPRO_OPC_SLT_U, TILEPRO_OPC_SNEB, TILEPRO_OPC_SNEH, TILEPRO_OPC_SNE,
+  TILEPRO_OPC_SRAB, TILEPRO_OPC_SRAH, TILEPRO_OPC_SRA, TILEPRO_OPC_SUBB,
+  TILEPRO_OPC_SUBH, TILEPRO_OPC_SUB, TILEPRO_OPC_XOR, TILEPRO_OPC_DWORD_ALIGN,
   BITFIELD(18, 3) /* index 630 */,
   CHILD(639), CHILD(642), CHILD(645), CHILD(648), CHILD(651), CHILD(654),
   CHILD(657), CHILD(660),
   BITFIELD(21, 1) /* index 639 */,
-  TILE_OPC_ADDS, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDS, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 642 */,
-  TILE_OPC_SUBS, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBS, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 645 */,
-  TILE_OPC_ADDBS_U, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDBS_U, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 648 */,
-  TILE_OPC_ADDHS, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDHS, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 651 */,
-  TILE_OPC_SUBBS_U, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBBS_U, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 654 */,
-  TILE_OPC_SUBHS, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBHS, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 657 */,
-  TILE_OPC_PACKHS, TILE_OPC_NONE,
+  TILEPRO_OPC_PACKHS, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 660 */,
-  TILE_OPC_PACKBS_U, TILE_OPC_NONE,
+  TILEPRO_OPC_PACKBS_U, TILEPRO_OPC_NONE,
   BITFIELD(18, 4) /* index 663 */,
-  TILE_OPC_NONE, TILE_OPC_ADDB_SN, TILE_OPC_ADDH_SN, TILE_OPC_ADD_SN,
-  TILE_OPC_ADIFFB_U_SN, TILE_OPC_ADIFFH_SN, TILE_OPC_AND_SN,
-  TILE_OPC_AVGB_U_SN, TILE_OPC_AVGH_SN, TILE_OPC_CRC32_32_SN,
-  TILE_OPC_CRC32_8_SN, TILE_OPC_INTHB_SN, TILE_OPC_INTHH_SN,
-  TILE_OPC_INTLB_SN, TILE_OPC_INTLH_SN, TILE_OPC_MAXB_U_SN,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_ADDB_SN, TILEPRO_OPC_ADDH_SN,
+  TILEPRO_OPC_ADD_SN, TILEPRO_OPC_ADIFFB_U_SN, TILEPRO_OPC_ADIFFH_SN,
+  TILEPRO_OPC_AND_SN, TILEPRO_OPC_AVGB_U_SN, TILEPRO_OPC_AVGH_SN,
+  TILEPRO_OPC_CRC32_32_SN, TILEPRO_OPC_CRC32_8_SN, TILEPRO_OPC_INTHB_SN,
+  TILEPRO_OPC_INTHH_SN, TILEPRO_OPC_INTLB_SN, TILEPRO_OPC_INTLH_SN,
+  TILEPRO_OPC_MAXB_U_SN,
   BITFIELD(18, 4) /* index 680 */,
-  TILE_OPC_MAXH_SN, TILE_OPC_MINB_U_SN, TILE_OPC_MINH_SN, TILE_OPC_MNZB_SN,
-  TILE_OPC_MNZH_SN, TILE_OPC_MNZ_SN, TILE_OPC_MULHHA_SS_SN,
-  TILE_OPC_MULHHA_SU_SN, TILE_OPC_MULHHA_UU_SN, TILE_OPC_MULHHSA_UU_SN,
-  TILE_OPC_MULHH_SS_SN, TILE_OPC_MULHH_SU_SN, TILE_OPC_MULHH_UU_SN,
-  TILE_OPC_MULHLA_SS_SN, TILE_OPC_MULHLA_SU_SN, TILE_OPC_MULHLA_US_SN,
+  TILEPRO_OPC_MAXH_SN, TILEPRO_OPC_MINB_U_SN, TILEPRO_OPC_MINH_SN,
+  TILEPRO_OPC_MNZB_SN, TILEPRO_OPC_MNZH_SN, TILEPRO_OPC_MNZ_SN,
+  TILEPRO_OPC_MULHHA_SS_SN, TILEPRO_OPC_MULHHA_SU_SN,
+  TILEPRO_OPC_MULHHA_UU_SN, TILEPRO_OPC_MULHHSA_UU_SN,
+  TILEPRO_OPC_MULHH_SS_SN, TILEPRO_OPC_MULHH_SU_SN, TILEPRO_OPC_MULHH_UU_SN,
+  TILEPRO_OPC_MULHLA_SS_SN, TILEPRO_OPC_MULHLA_SU_SN,
+  TILEPRO_OPC_MULHLA_US_SN,
   BITFIELD(18, 4) /* index 697 */,
-  TILE_OPC_MULHLA_UU_SN, TILE_OPC_MULHLSA_UU_SN, TILE_OPC_MULHL_SS_SN,
-  TILE_OPC_MULHL_SU_SN, TILE_OPC_MULHL_US_SN, TILE_OPC_MULHL_UU_SN,
-  TILE_OPC_MULLLA_SS_SN, TILE_OPC_MULLLA_SU_SN, TILE_OPC_MULLLA_UU_SN,
-  TILE_OPC_MULLLSA_UU_SN, TILE_OPC_MULLL_SS_SN, TILE_OPC_MULLL_SU_SN,
-  TILE_OPC_MULLL_UU_SN, TILE_OPC_MVNZ_SN, TILE_OPC_MVZ_SN, TILE_OPC_MZB_SN,
+  TILEPRO_OPC_MULHLA_UU_SN, TILEPRO_OPC_MULHLSA_UU_SN,
+  TILEPRO_OPC_MULHL_SS_SN, TILEPRO_OPC_MULHL_SU_SN, TILEPRO_OPC_MULHL_US_SN,
+  TILEPRO_OPC_MULHL_UU_SN, TILEPRO_OPC_MULLLA_SS_SN, TILEPRO_OPC_MULLLA_SU_SN,
+  TILEPRO_OPC_MULLLA_UU_SN, TILEPRO_OPC_MULLLSA_UU_SN,
+  TILEPRO_OPC_MULLL_SS_SN, TILEPRO_OPC_MULLL_SU_SN, TILEPRO_OPC_MULLL_UU_SN,
+  TILEPRO_OPC_MVNZ_SN, TILEPRO_OPC_MVZ_SN, TILEPRO_OPC_MZB_SN,
   BITFIELD(18, 4) /* index 714 */,
-  TILE_OPC_MZH_SN, TILE_OPC_MZ_SN, TILE_OPC_NOR_SN, CHILD(731),
-  TILE_OPC_PACKHB_SN, TILE_OPC_PACKLB_SN, TILE_OPC_RL_SN, TILE_OPC_S1A_SN,
-  TILE_OPC_S2A_SN, TILE_OPC_S3A_SN, TILE_OPC_SADAB_U_SN, TILE_OPC_SADAH_SN,
-  TILE_OPC_SADAH_U_SN, TILE_OPC_SADB_U_SN, TILE_OPC_SADH_SN,
-  TILE_OPC_SADH_U_SN,
+  TILEPRO_OPC_MZH_SN, TILEPRO_OPC_MZ_SN, TILEPRO_OPC_NOR_SN, CHILD(731),
+  TILEPRO_OPC_PACKHB_SN, TILEPRO_OPC_PACKLB_SN, TILEPRO_OPC_RL_SN,
+  TILEPRO_OPC_S1A_SN, TILEPRO_OPC_S2A_SN, TILEPRO_OPC_S3A_SN,
+  TILEPRO_OPC_SADAB_U_SN, TILEPRO_OPC_SADAH_SN, TILEPRO_OPC_SADAH_U_SN,
+  TILEPRO_OPC_SADB_U_SN, TILEPRO_OPC_SADH_SN, TILEPRO_OPC_SADH_U_SN,
   BITFIELD(12, 2) /* index 731 */,
-  TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(736),
+  TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, CHILD(736),
   BITFIELD(14, 2) /* index 736 */,
-  TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(741),
+  TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, CHILD(741),
   BITFIELD(16, 2) /* index 741 */,
-  TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_MOVE_SN,
+  TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN,
+  TILEPRO_OPC_MOVE_SN,
   BITFIELD(18, 4) /* index 746 */,
-  TILE_OPC_SEQB_SN, TILE_OPC_SEQH_SN, TILE_OPC_SEQ_SN, TILE_OPC_SHLB_SN,
-  TILE_OPC_SHLH_SN, TILE_OPC_SHL_SN, TILE_OPC_SHRB_SN, TILE_OPC_SHRH_SN,
-  TILE_OPC_SHR_SN, TILE_OPC_SLTB_SN, TILE_OPC_SLTB_U_SN, TILE_OPC_SLTEB_SN,
-  TILE_OPC_SLTEB_U_SN, TILE_OPC_SLTEH_SN, TILE_OPC_SLTEH_U_SN,
-  TILE_OPC_SLTE_SN,
+  TILEPRO_OPC_SEQB_SN, TILEPRO_OPC_SEQH_SN, TILEPRO_OPC_SEQ_SN,
+  TILEPRO_OPC_SHLB_SN, TILEPRO_OPC_SHLH_SN, TILEPRO_OPC_SHL_SN,
+  TILEPRO_OPC_SHRB_SN, TILEPRO_OPC_SHRH_SN, TILEPRO_OPC_SHR_SN,
+  TILEPRO_OPC_SLTB_SN, TILEPRO_OPC_SLTB_U_SN, TILEPRO_OPC_SLTEB_SN,
+  TILEPRO_OPC_SLTEB_U_SN, TILEPRO_OPC_SLTEH_SN, TILEPRO_OPC_SLTEH_U_SN,
+  TILEPRO_OPC_SLTE_SN,
   BITFIELD(18, 4) /* index 763 */,
-  TILE_OPC_SLTE_U_SN, TILE_OPC_SLTH_SN, TILE_OPC_SLTH_U_SN, TILE_OPC_SLT_SN,
-  TILE_OPC_SLT_U_SN, TILE_OPC_SNEB_SN, TILE_OPC_SNEH_SN, TILE_OPC_SNE_SN,
-  TILE_OPC_SRAB_SN, TILE_OPC_SRAH_SN, TILE_OPC_SRA_SN, TILE_OPC_SUBB_SN,
-  TILE_OPC_SUBH_SN, TILE_OPC_SUB_SN, TILE_OPC_XOR_SN, TILE_OPC_DWORD_ALIGN_SN,
+  TILEPRO_OPC_SLTE_U_SN, TILEPRO_OPC_SLTH_SN, TILEPRO_OPC_SLTH_U_SN,
+  TILEPRO_OPC_SLT_SN, TILEPRO_OPC_SLT_U_SN, TILEPRO_OPC_SNEB_SN,
+  TILEPRO_OPC_SNEH_SN, TILEPRO_OPC_SNE_SN, TILEPRO_OPC_SRAB_SN,
+  TILEPRO_OPC_SRAH_SN, TILEPRO_OPC_SRA_SN, TILEPRO_OPC_SUBB_SN,
+  TILEPRO_OPC_SUBH_SN, TILEPRO_OPC_SUB_SN, TILEPRO_OPC_XOR_SN,
+  TILEPRO_OPC_DWORD_ALIGN_SN,
   BITFIELD(18, 3) /* index 780 */,
   CHILD(789), CHILD(792), CHILD(795), CHILD(798), CHILD(801), CHILD(804),
   CHILD(807), CHILD(810),
   BITFIELD(21, 1) /* index 789 */,
-  TILE_OPC_ADDS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDS_SN, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 792 */,
-  TILE_OPC_SUBS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBS_SN, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 795 */,
-  TILE_OPC_ADDBS_U_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDBS_U_SN, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 798 */,
-  TILE_OPC_ADDHS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDHS_SN, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 801 */,
-  TILE_OPC_SUBBS_U_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBBS_U_SN, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 804 */,
-  TILE_OPC_SUBHS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBHS_SN, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 807 */,
-  TILE_OPC_PACKHS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_PACKHS_SN, TILEPRO_OPC_NONE,
   BITFIELD(21, 1) /* index 810 */,
-  TILE_OPC_PACKBS_U_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_PACKBS_U_SN, TILEPRO_OPC_NONE,
   BITFIELD(6, 2) /* index 813 */,
-  TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(818),
+  TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
+  CHILD(818),
   BITFIELD(8, 2) /* index 818 */,
-  TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(823),
+  TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
+  CHILD(823),
   BITFIELD(10, 2) /* index 823 */,
-  TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_MOVELI_SN,
+  TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
+  TILEPRO_OPC_MOVELI_SN,
   BITFIELD(6, 2) /* index 828 */,
-  TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(833),
+  TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, CHILD(833),
   BITFIELD(8, 2) /* index 833 */,
-  TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(838),
+  TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, CHILD(838),
   BITFIELD(10, 2) /* index 838 */,
-  TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_MOVELI,
+  TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_MOVELI,
   BITFIELD(0, 2) /* index 843 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(848),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(848),
   BITFIELD(2, 2) /* index 848 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(853),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(853),
   BITFIELD(4, 2) /* index 853 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(858),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(858),
   BITFIELD(6, 2) /* index 858 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(863),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(863),
   BITFIELD(8, 2) /* index 863 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(868),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(868),
   BITFIELD(10, 2) /* index 868 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_INFOL,
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_INFOL,
   BITFIELD(20, 2) /* index 873 */,
-  TILE_OPC_NONE, TILE_OPC_ADDIB, TILE_OPC_ADDIH, TILE_OPC_ADDI,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_ADDIB, TILEPRO_OPC_ADDIH, TILEPRO_OPC_ADDI,
   BITFIELD(20, 2) /* index 878 */,
-  TILE_OPC_MAXIB_U, TILE_OPC_MAXIH, TILE_OPC_MINIB_U, TILE_OPC_MINIH,
+  TILEPRO_OPC_MAXIB_U, TILEPRO_OPC_MAXIH, TILEPRO_OPC_MINIB_U,
+  TILEPRO_OPC_MINIH,
   BITFIELD(20, 2) /* index 883 */,
-  CHILD(888), TILE_OPC_SEQIB, TILE_OPC_SEQIH, TILE_OPC_SEQI,
+  CHILD(888), TILEPRO_OPC_SEQIB, TILEPRO_OPC_SEQIH, TILEPRO_OPC_SEQI,
   BITFIELD(6, 2) /* index 888 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(893),
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(893),
   BITFIELD(8, 2) /* index 893 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(898),
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(898),
   BITFIELD(10, 2) /* index 898 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_MOVEI,
   BITFIELD(20, 2) /* index 903 */,
-  TILE_OPC_SLTIB, TILE_OPC_SLTIB_U, TILE_OPC_SLTIH, TILE_OPC_SLTIH_U,
+  TILEPRO_OPC_SLTIB, TILEPRO_OPC_SLTIB_U, TILEPRO_OPC_SLTIH,
+  TILEPRO_OPC_SLTIH_U,
   BITFIELD(20, 2) /* index 908 */,
-  TILE_OPC_SLTI, TILE_OPC_SLTI_U, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_SLTI, TILEPRO_OPC_SLTI_U, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(20, 2) /* index 913 */,
-  TILE_OPC_NONE, TILE_OPC_ADDIB_SN, TILE_OPC_ADDIH_SN, TILE_OPC_ADDI_SN,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_ADDIB_SN, TILEPRO_OPC_ADDIH_SN,
+  TILEPRO_OPC_ADDI_SN,
   BITFIELD(20, 2) /* index 918 */,
-  TILE_OPC_MAXIB_U_SN, TILE_OPC_MAXIH_SN, TILE_OPC_MINIB_U_SN,
-  TILE_OPC_MINIH_SN,
+  TILEPRO_OPC_MAXIB_U_SN, TILEPRO_OPC_MAXIH_SN, TILEPRO_OPC_MINIB_U_SN,
+  TILEPRO_OPC_MINIH_SN,
   BITFIELD(20, 2) /* index 923 */,
-  CHILD(928), TILE_OPC_SEQIB_SN, TILE_OPC_SEQIH_SN, TILE_OPC_SEQI_SN,
+  CHILD(928), TILEPRO_OPC_SEQIB_SN, TILEPRO_OPC_SEQIH_SN, TILEPRO_OPC_SEQI_SN,
   BITFIELD(6, 2) /* index 928 */,
-  TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(933),
+  TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, CHILD(933),
   BITFIELD(8, 2) /* index 933 */,
-  TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(938),
+  TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, CHILD(938),
   BITFIELD(10, 2) /* index 938 */,
-  TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_MOVEI_SN,
+  TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN,
+  TILEPRO_OPC_MOVEI_SN,
   BITFIELD(20, 2) /* index 943 */,
-  TILE_OPC_SLTIB_SN, TILE_OPC_SLTIB_U_SN, TILE_OPC_SLTIH_SN,
-  TILE_OPC_SLTIH_U_SN,
+  TILEPRO_OPC_SLTIB_SN, TILEPRO_OPC_SLTIB_U_SN, TILEPRO_OPC_SLTIH_SN,
+  TILEPRO_OPC_SLTIH_U_SN,
   BITFIELD(20, 2) /* index 948 */,
-  TILE_OPC_SLTI_SN, TILE_OPC_SLTI_U_SN, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_SLTI_SN, TILEPRO_OPC_SLTI_U_SN, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE,
   BITFIELD(20, 2) /* index 953 */,
-  TILE_OPC_NONE, CHILD(958), TILE_OPC_XORI, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, CHILD(958), TILEPRO_OPC_XORI, TILEPRO_OPC_NONE,
   BITFIELD(0, 2) /* index 958 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(963),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(963),
   BITFIELD(2, 2) /* index 963 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(968),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(968),
   BITFIELD(4, 2) /* index 968 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(973),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(973),
   BITFIELD(6, 2) /* index 973 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(978),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(978),
   BITFIELD(8, 2) /* index 978 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(983),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(983),
   BITFIELD(10, 2) /* index 983 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_INFO,
   BITFIELD(20, 2) /* index 988 */,
-  TILE_OPC_NONE, TILE_OPC_ANDI_SN, TILE_OPC_XORI_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_ANDI_SN, TILEPRO_OPC_XORI_SN,
+  TILEPRO_OPC_NONE,
   BITFIELD(17, 5) /* index 993 */,
-  TILE_OPC_NONE, TILE_OPC_RLI, TILE_OPC_SHLIB, TILE_OPC_SHLIH, TILE_OPC_SHLI,
-  TILE_OPC_SHRIB, TILE_OPC_SHRIH, TILE_OPC_SHRI, TILE_OPC_SRAIB,
-  TILE_OPC_SRAIH, TILE_OPC_SRAI, CHILD(1026), TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_RLI, TILEPRO_OPC_SHLIB, TILEPRO_OPC_SHLIH,
+  TILEPRO_OPC_SHLI, TILEPRO_OPC_SHRIB, TILEPRO_OPC_SHRIH, TILEPRO_OPC_SHRI,
+  TILEPRO_OPC_SRAIB, TILEPRO_OPC_SRAIH, TILEPRO_OPC_SRAI, CHILD(1026),
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(12, 4) /* index 1026 */,
-  TILE_OPC_NONE, CHILD(1043), CHILD(1046), CHILD(1049), CHILD(1052),
+  TILEPRO_OPC_NONE, CHILD(1043), CHILD(1046), CHILD(1049), CHILD(1052),
   CHILD(1055), CHILD(1058), CHILD(1061), CHILD(1064), CHILD(1067),
-  CHILD(1070), CHILD(1073), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE,
+  CHILD(1070), CHILD(1073), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1043 */,
-  TILE_OPC_BITX, TILE_OPC_NONE,
+  TILEPRO_OPC_BITX, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1046 */,
-  TILE_OPC_BYTEX, TILE_OPC_NONE,
+  TILEPRO_OPC_BYTEX, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1049 */,
-  TILE_OPC_CLZ, TILE_OPC_NONE,
+  TILEPRO_OPC_CLZ, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1052 */,
-  TILE_OPC_CTZ, TILE_OPC_NONE,
+  TILEPRO_OPC_CTZ, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1055 */,
-  TILE_OPC_FNOP, TILE_OPC_NONE,
+  TILEPRO_OPC_FNOP, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1058 */,
-  TILE_OPC_NOP, TILE_OPC_NONE,
+  TILEPRO_OPC_NOP, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1061 */,
-  TILE_OPC_PCNT, TILE_OPC_NONE,
+  TILEPRO_OPC_PCNT, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1064 */,
-  TILE_OPC_TBLIDXB0, TILE_OPC_NONE,
+  TILEPRO_OPC_TBLIDXB0, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1067 */,
-  TILE_OPC_TBLIDXB1, TILE_OPC_NONE,
+  TILEPRO_OPC_TBLIDXB1, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1070 */,
-  TILE_OPC_TBLIDXB2, TILE_OPC_NONE,
+  TILEPRO_OPC_TBLIDXB2, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1073 */,
-  TILE_OPC_TBLIDXB3, TILE_OPC_NONE,
+  TILEPRO_OPC_TBLIDXB3, TILEPRO_OPC_NONE,
   BITFIELD(17, 5) /* index 1076 */,
-  TILE_OPC_NONE, TILE_OPC_RLI_SN, TILE_OPC_SHLIB_SN, TILE_OPC_SHLIH_SN,
-  TILE_OPC_SHLI_SN, TILE_OPC_SHRIB_SN, TILE_OPC_SHRIH_SN, TILE_OPC_SHRI_SN,
-  TILE_OPC_SRAIB_SN, TILE_OPC_SRAIH_SN, TILE_OPC_SRAI_SN, CHILD(1109),
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_RLI_SN, TILEPRO_OPC_SHLIB_SN,
+  TILEPRO_OPC_SHLIH_SN, TILEPRO_OPC_SHLI_SN, TILEPRO_OPC_SHRIB_SN,
+  TILEPRO_OPC_SHRIH_SN, TILEPRO_OPC_SHRI_SN, TILEPRO_OPC_SRAIB_SN,
+  TILEPRO_OPC_SRAIH_SN, TILEPRO_OPC_SRAI_SN, CHILD(1109), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(12, 4) /* index 1109 */,
-  TILE_OPC_NONE, CHILD(1126), CHILD(1129), CHILD(1132), CHILD(1135),
+  TILEPRO_OPC_NONE, CHILD(1126), CHILD(1129), CHILD(1132), CHILD(1135),
   CHILD(1055), CHILD(1058), CHILD(1138), CHILD(1141), CHILD(1144),
-  CHILD(1147), CHILD(1150), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE,
+  CHILD(1147), CHILD(1150), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1126 */,
-  TILE_OPC_BITX_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_BITX_SN, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1129 */,
-  TILE_OPC_BYTEX_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_BYTEX_SN, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1132 */,
-  TILE_OPC_CLZ_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_CLZ_SN, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1135 */,
-  TILE_OPC_CTZ_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_CTZ_SN, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1138 */,
-  TILE_OPC_PCNT_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_PCNT_SN, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1141 */,
-  TILE_OPC_TBLIDXB0_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_TBLIDXB0_SN, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1144 */,
-  TILE_OPC_TBLIDXB1_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_TBLIDXB1_SN, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1147 */,
-  TILE_OPC_TBLIDXB2_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_TBLIDXB2_SN, TILEPRO_OPC_NONE,
   BITFIELD(16, 1) /* index 1150 */,
-  TILE_OPC_TBLIDXB3_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_TBLIDXB3_SN, TILEPRO_OPC_NONE,
 };
 
 static const unsigned short decode_X1_fsm[1540] =
 {
   BITFIELD(54, 9) /* index 0 */,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, CHILD(513), CHILD(561), CHILD(594),
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(641), CHILD(689),
-  CHILD(722), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(766),
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  CHILD(513), CHILD(561), CHILD(594), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(641),
+  CHILD(689), CHILD(722), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(766),
   CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
   CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
   CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
@@ -1596,594 +1655,641 @@ static const unsigned short decode_X1_fsm[1540] =
   CHILD(826), CHILD(826), CHILD(826), CHILD(843), CHILD(843), CHILD(843),
   CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
   CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
-  CHILD(843), CHILD(860), CHILD(899), CHILD(923), CHILD(932), TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, CHILD(941), CHILD(950), CHILD(974), CHILD(983),
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
-  TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, CHILD(992),
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  CHILD(1334), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
-  TILE_OPC_J, TILE_OPC_J, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
-  TILE_OPC_JAL, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  CHILD(843), CHILD(860), CHILD(899), CHILD(923), CHILD(932),
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  CHILD(941), CHILD(950), CHILD(974), CHILD(983), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM,
+  TILEPRO_OPC_MM, TILEPRO_OPC_MM, TILEPRO_OPC_MM, CHILD(992),
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, CHILD(1334),
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J,
+  TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_J, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL,
+  TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_JAL, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(49, 5) /* index 513 */,
-  TILE_OPC_NONE, TILE_OPC_ADDB, TILE_OPC_ADDH, TILE_OPC_ADD, TILE_OPC_AND,
-  TILE_OPC_INTHB, TILE_OPC_INTHH, TILE_OPC_INTLB, TILE_OPC_INTLH,
-  TILE_OPC_JALRP, TILE_OPC_JALR, TILE_OPC_JRP, TILE_OPC_JR, TILE_OPC_LNK,
-  TILE_OPC_MAXB_U, TILE_OPC_MAXH, TILE_OPC_MINB_U, TILE_OPC_MINH,
-  TILE_OPC_MNZB, TILE_OPC_MNZH, TILE_OPC_MNZ, TILE_OPC_MZB, TILE_OPC_MZH,
-  TILE_OPC_MZ, TILE_OPC_NOR, CHILD(546), TILE_OPC_PACKHB, TILE_OPC_PACKLB,
-  TILE_OPC_RL, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_S3A,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_ADDB, TILEPRO_OPC_ADDH, TILEPRO_OPC_ADD,
+  TILEPRO_OPC_AND, TILEPRO_OPC_INTHB, TILEPRO_OPC_INTHH, TILEPRO_OPC_INTLB,
+  TILEPRO_OPC_INTLH, TILEPRO_OPC_JALRP, TILEPRO_OPC_JALR, TILEPRO_OPC_JRP,
+  TILEPRO_OPC_JR, TILEPRO_OPC_LNK, TILEPRO_OPC_MAXB_U, TILEPRO_OPC_MAXH,
+  TILEPRO_OPC_MINB_U, TILEPRO_OPC_MINH, TILEPRO_OPC_MNZB, TILEPRO_OPC_MNZH,
+  TILEPRO_OPC_MNZ, TILEPRO_OPC_MZB, TILEPRO_OPC_MZH, TILEPRO_OPC_MZ,
+  TILEPRO_OPC_NOR, CHILD(546), TILEPRO_OPC_PACKHB, TILEPRO_OPC_PACKLB,
+  TILEPRO_OPC_RL, TILEPRO_OPC_S1A, TILEPRO_OPC_S2A, TILEPRO_OPC_S3A,
   BITFIELD(43, 2) /* index 546 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(551),
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(551),
   BITFIELD(45, 2) /* index 551 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(556),
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(556),
   BITFIELD(47, 2) /* index 556 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_MOVE,
   BITFIELD(49, 5) /* index 561 */,
-  TILE_OPC_SB, TILE_OPC_SEQB, TILE_OPC_SEQH, TILE_OPC_SEQ, TILE_OPC_SHLB,
-  TILE_OPC_SHLH, TILE_OPC_SHL, TILE_OPC_SHRB, TILE_OPC_SHRH, TILE_OPC_SHR,
-  TILE_OPC_SH, TILE_OPC_SLTB, TILE_OPC_SLTB_U, TILE_OPC_SLTEB,
-  TILE_OPC_SLTEB_U, TILE_OPC_SLTEH, TILE_OPC_SLTEH_U, TILE_OPC_SLTE,
-  TILE_OPC_SLTE_U, TILE_OPC_SLTH, TILE_OPC_SLTH_U, TILE_OPC_SLT,
-  TILE_OPC_SLT_U, TILE_OPC_SNEB, TILE_OPC_SNEH, TILE_OPC_SNE, TILE_OPC_SRAB,
-  TILE_OPC_SRAH, TILE_OPC_SRA, TILE_OPC_SUBB, TILE_OPC_SUBH, TILE_OPC_SUB,
+  TILEPRO_OPC_SB, TILEPRO_OPC_SEQB, TILEPRO_OPC_SEQH, TILEPRO_OPC_SEQ,
+  TILEPRO_OPC_SHLB, TILEPRO_OPC_SHLH, TILEPRO_OPC_SHL, TILEPRO_OPC_SHRB,
+  TILEPRO_OPC_SHRH, TILEPRO_OPC_SHR, TILEPRO_OPC_SH, TILEPRO_OPC_SLTB,
+  TILEPRO_OPC_SLTB_U, TILEPRO_OPC_SLTEB, TILEPRO_OPC_SLTEB_U,
+  TILEPRO_OPC_SLTEH, TILEPRO_OPC_SLTEH_U, TILEPRO_OPC_SLTE,
+  TILEPRO_OPC_SLTE_U, TILEPRO_OPC_SLTH, TILEPRO_OPC_SLTH_U, TILEPRO_OPC_SLT,
+  TILEPRO_OPC_SLT_U, TILEPRO_OPC_SNEB, TILEPRO_OPC_SNEH, TILEPRO_OPC_SNE,
+  TILEPRO_OPC_SRAB, TILEPRO_OPC_SRAH, TILEPRO_OPC_SRA, TILEPRO_OPC_SUBB,
+  TILEPRO_OPC_SUBH, TILEPRO_OPC_SUB,
   BITFIELD(49, 4) /* index 594 */,
   CHILD(611), CHILD(614), CHILD(617), CHILD(620), CHILD(623), CHILD(626),
-  CHILD(629), CHILD(632), CHILD(635), CHILD(638), TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  CHILD(629), CHILD(632), CHILD(635), CHILD(638), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 611 */,
-  TILE_OPC_SW, TILE_OPC_NONE,
+  TILEPRO_OPC_SW, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 614 */,
-  TILE_OPC_XOR, TILE_OPC_NONE,
+  TILEPRO_OPC_XOR, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 617 */,
-  TILE_OPC_ADDS, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDS, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 620 */,
-  TILE_OPC_SUBS, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBS, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 623 */,
-  TILE_OPC_ADDBS_U, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDBS_U, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 626 */,
-  TILE_OPC_ADDHS, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDHS, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 629 */,
-  TILE_OPC_SUBBS_U, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBBS_U, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 632 */,
-  TILE_OPC_SUBHS, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBHS, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 635 */,
-  TILE_OPC_PACKHS, TILE_OPC_NONE,
+  TILEPRO_OPC_PACKHS, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 638 */,
-  TILE_OPC_PACKBS_U, TILE_OPC_NONE,
+  TILEPRO_OPC_PACKBS_U, TILEPRO_OPC_NONE,
   BITFIELD(49, 5) /* index 641 */,
-  TILE_OPC_NONE, TILE_OPC_ADDB_SN, TILE_OPC_ADDH_SN, TILE_OPC_ADD_SN,
-  TILE_OPC_AND_SN, TILE_OPC_INTHB_SN, TILE_OPC_INTHH_SN, TILE_OPC_INTLB_SN,
-  TILE_OPC_INTLH_SN, TILE_OPC_JALRP, TILE_OPC_JALR, TILE_OPC_JRP, TILE_OPC_JR,
-  TILE_OPC_LNK_SN, TILE_OPC_MAXB_U_SN, TILE_OPC_MAXH_SN, TILE_OPC_MINB_U_SN,
-  TILE_OPC_MINH_SN, TILE_OPC_MNZB_SN, TILE_OPC_MNZH_SN, TILE_OPC_MNZ_SN,
-  TILE_OPC_MZB_SN, TILE_OPC_MZH_SN, TILE_OPC_MZ_SN, TILE_OPC_NOR_SN,
-  CHILD(674), TILE_OPC_PACKHB_SN, TILE_OPC_PACKLB_SN, TILE_OPC_RL_SN,
-  TILE_OPC_S1A_SN, TILE_OPC_S2A_SN, TILE_OPC_S3A_SN,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_ADDB_SN, TILEPRO_OPC_ADDH_SN,
+  TILEPRO_OPC_ADD_SN, TILEPRO_OPC_AND_SN, TILEPRO_OPC_INTHB_SN,
+  TILEPRO_OPC_INTHH_SN, TILEPRO_OPC_INTLB_SN, TILEPRO_OPC_INTLH_SN,
+  TILEPRO_OPC_JALRP, TILEPRO_OPC_JALR, TILEPRO_OPC_JRP, TILEPRO_OPC_JR,
+  TILEPRO_OPC_LNK_SN, TILEPRO_OPC_MAXB_U_SN, TILEPRO_OPC_MAXH_SN,
+  TILEPRO_OPC_MINB_U_SN, TILEPRO_OPC_MINH_SN, TILEPRO_OPC_MNZB_SN,
+  TILEPRO_OPC_MNZH_SN, TILEPRO_OPC_MNZ_SN, TILEPRO_OPC_MZB_SN,
+  TILEPRO_OPC_MZH_SN, TILEPRO_OPC_MZ_SN, TILEPRO_OPC_NOR_SN, CHILD(674),
+  TILEPRO_OPC_PACKHB_SN, TILEPRO_OPC_PACKLB_SN, TILEPRO_OPC_RL_SN,
+  TILEPRO_OPC_S1A_SN, TILEPRO_OPC_S2A_SN, TILEPRO_OPC_S3A_SN,
   BITFIELD(43, 2) /* index 674 */,
-  TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(679),
+  TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, CHILD(679),
   BITFIELD(45, 2) /* index 679 */,
-  TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(684),
+  TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, CHILD(684),
   BITFIELD(47, 2) /* index 684 */,
-  TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_MOVE_SN,
+  TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN, TILEPRO_OPC_OR_SN,
+  TILEPRO_OPC_MOVE_SN,
   BITFIELD(49, 5) /* index 689 */,
-  TILE_OPC_SB, TILE_OPC_SEQB_SN, TILE_OPC_SEQH_SN, TILE_OPC_SEQ_SN,
-  TILE_OPC_SHLB_SN, TILE_OPC_SHLH_SN, TILE_OPC_SHL_SN, TILE_OPC_SHRB_SN,
-  TILE_OPC_SHRH_SN, TILE_OPC_SHR_SN, TILE_OPC_SH, TILE_OPC_SLTB_SN,
-  TILE_OPC_SLTB_U_SN, TILE_OPC_SLTEB_SN, TILE_OPC_SLTEB_U_SN,
-  TILE_OPC_SLTEH_SN, TILE_OPC_SLTEH_U_SN, TILE_OPC_SLTE_SN,
-  TILE_OPC_SLTE_U_SN, TILE_OPC_SLTH_SN, TILE_OPC_SLTH_U_SN, TILE_OPC_SLT_SN,
-  TILE_OPC_SLT_U_SN, TILE_OPC_SNEB_SN, TILE_OPC_SNEH_SN, TILE_OPC_SNE_SN,
-  TILE_OPC_SRAB_SN, TILE_OPC_SRAH_SN, TILE_OPC_SRA_SN, TILE_OPC_SUBB_SN,
-  TILE_OPC_SUBH_SN, TILE_OPC_SUB_SN,
+  TILEPRO_OPC_SB, TILEPRO_OPC_SEQB_SN, TILEPRO_OPC_SEQH_SN,
+  TILEPRO_OPC_SEQ_SN, TILEPRO_OPC_SHLB_SN, TILEPRO_OPC_SHLH_SN,
+  TILEPRO_OPC_SHL_SN, TILEPRO_OPC_SHRB_SN, TILEPRO_OPC_SHRH_SN,
+  TILEPRO_OPC_SHR_SN, TILEPRO_OPC_SH, TILEPRO_OPC_SLTB_SN,
+  TILEPRO_OPC_SLTB_U_SN, TILEPRO_OPC_SLTEB_SN, TILEPRO_OPC_SLTEB_U_SN,
+  TILEPRO_OPC_SLTEH_SN, TILEPRO_OPC_SLTEH_U_SN, TILEPRO_OPC_SLTE_SN,
+  TILEPRO_OPC_SLTE_U_SN, TILEPRO_OPC_SLTH_SN, TILEPRO_OPC_SLTH_U_SN,
+  TILEPRO_OPC_SLT_SN, TILEPRO_OPC_SLT_U_SN, TILEPRO_OPC_SNEB_SN,
+  TILEPRO_OPC_SNEH_SN, TILEPRO_OPC_SNE_SN, TILEPRO_OPC_SRAB_SN,
+  TILEPRO_OPC_SRAH_SN, TILEPRO_OPC_SRA_SN, TILEPRO_OPC_SUBB_SN,
+  TILEPRO_OPC_SUBH_SN, TILEPRO_OPC_SUB_SN,
   BITFIELD(49, 4) /* index 722 */,
   CHILD(611), CHILD(739), CHILD(742), CHILD(745), CHILD(748), CHILD(751),
-  CHILD(754), CHILD(757), CHILD(760), CHILD(763), TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  CHILD(754), CHILD(757), CHILD(760), CHILD(763), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 739 */,
-  TILE_OPC_XOR_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_XOR_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 742 */,
-  TILE_OPC_ADDS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDS_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 745 */,
-  TILE_OPC_SUBS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBS_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 748 */,
-  TILE_OPC_ADDBS_U_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDBS_U_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 751 */,
-  TILE_OPC_ADDHS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_ADDHS_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 754 */,
-  TILE_OPC_SUBBS_U_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBBS_U_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 757 */,
-  TILE_OPC_SUBHS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SUBHS_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 760 */,
-  TILE_OPC_PACKHS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_PACKHS_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 763 */,
-  TILE_OPC_PACKBS_U_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_PACKBS_U_SN, TILEPRO_OPC_NONE,
   BITFIELD(37, 2) /* index 766 */,
-  TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(771),
+  TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
+  CHILD(771),
   BITFIELD(39, 2) /* index 771 */,
-  TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(776),
+  TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
+  CHILD(776),
   BITFIELD(41, 2) /* index 776 */,
-  TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_MOVELI_SN,
+  TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN, TILEPRO_OPC_ADDLI_SN,
+  TILEPRO_OPC_MOVELI_SN,
   BITFIELD(37, 2) /* index 781 */,
-  TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(786),
+  TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, CHILD(786),
   BITFIELD(39, 2) /* index 786 */,
-  TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(791),
+  TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, CHILD(791),
   BITFIELD(41, 2) /* index 791 */,
-  TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_MOVELI,
+  TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_ADDLI, TILEPRO_OPC_MOVELI,
   BITFIELD(31, 2) /* index 796 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(801),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(801),
   BITFIELD(33, 2) /* index 801 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(806),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(806),
   BITFIELD(35, 2) /* index 806 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(811),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(811),
   BITFIELD(37, 2) /* index 811 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(816),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(816),
   BITFIELD(39, 2) /* index 816 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(821),
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, CHILD(821),
   BITFIELD(41, 2) /* index 821 */,
-  TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_INFOL,
+  TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_AULI, TILEPRO_OPC_INFOL,
   BITFIELD(31, 4) /* index 826 */,
-  TILE_OPC_BZ, TILE_OPC_BZT, TILE_OPC_BNZ, TILE_OPC_BNZT, TILE_OPC_BGZ,
-  TILE_OPC_BGZT, TILE_OPC_BGEZ, TILE_OPC_BGEZT, TILE_OPC_BLZ, TILE_OPC_BLZT,
-  TILE_OPC_BLEZ, TILE_OPC_BLEZT, TILE_OPC_BBS, TILE_OPC_BBST, TILE_OPC_BBNS,
-  TILE_OPC_BBNST,
+  TILEPRO_OPC_BZ, TILEPRO_OPC_BZT, TILEPRO_OPC_BNZ, TILEPRO_OPC_BNZT,
+  TILEPRO_OPC_BGZ, TILEPRO_OPC_BGZT, TILEPRO_OPC_BGEZ, TILEPRO_OPC_BGEZT,
+  TILEPRO_OPC_BLZ, TILEPRO_OPC_BLZT, TILEPRO_OPC_BLEZ, TILEPRO_OPC_BLEZT,
+  TILEPRO_OPC_BBS, TILEPRO_OPC_BBST, TILEPRO_OPC_BBNS, TILEPRO_OPC_BBNST,
   BITFIELD(31, 4) /* index 843 */,
-  TILE_OPC_BZ_SN, TILE_OPC_BZT_SN, TILE_OPC_BNZ_SN, TILE_OPC_BNZT_SN,
-  TILE_OPC_BGZ_SN, TILE_OPC_BGZT_SN, TILE_OPC_BGEZ_SN, TILE_OPC_BGEZT_SN,
-  TILE_OPC_BLZ_SN, TILE_OPC_BLZT_SN, TILE_OPC_BLEZ_SN, TILE_OPC_BLEZT_SN,
-  TILE_OPC_BBS_SN, TILE_OPC_BBST_SN, TILE_OPC_BBNS_SN, TILE_OPC_BBNST_SN,
+  TILEPRO_OPC_BZ_SN, TILEPRO_OPC_BZT_SN, TILEPRO_OPC_BNZ_SN,
+  TILEPRO_OPC_BNZT_SN, TILEPRO_OPC_BGZ_SN, TILEPRO_OPC_BGZT_SN,
+  TILEPRO_OPC_BGEZ_SN, TILEPRO_OPC_BGEZT_SN, TILEPRO_OPC_BLZ_SN,
+  TILEPRO_OPC_BLZT_SN, TILEPRO_OPC_BLEZ_SN, TILEPRO_OPC_BLEZT_SN,
+  TILEPRO_OPC_BBS_SN, TILEPRO_OPC_BBST_SN, TILEPRO_OPC_BBNS_SN,
+  TILEPRO_OPC_BBNST_SN,
   BITFIELD(51, 3) /* index 860 */,
-  TILE_OPC_NONE, TILE_OPC_ADDIB, TILE_OPC_ADDIH, TILE_OPC_ADDI, CHILD(869),
-  TILE_OPC_MAXIB_U, TILE_OPC_MAXIH, TILE_OPC_MFSPR,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_ADDIB, TILEPRO_OPC_ADDIH, TILEPRO_OPC_ADDI,
+  CHILD(869), TILEPRO_OPC_MAXIB_U, TILEPRO_OPC_MAXIH, TILEPRO_OPC_MFSPR,
   BITFIELD(31, 2) /* index 869 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(874),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(874),
   BITFIELD(33, 2) /* index 874 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(879),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(879),
   BITFIELD(35, 2) /* index 879 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(884),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(884),
   BITFIELD(37, 2) /* index 884 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(889),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(889),
   BITFIELD(39, 2) /* index 889 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(894),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(894),
   BITFIELD(41, 2) /* index 894 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_INFO,
   BITFIELD(51, 3) /* index 899 */,
-  TILE_OPC_MINIB_U, TILE_OPC_MINIH, TILE_OPC_MTSPR, CHILD(908),
-  TILE_OPC_SEQIB, TILE_OPC_SEQIH, TILE_OPC_SEQI, TILE_OPC_SLTIB,
+  TILEPRO_OPC_MINIB_U, TILEPRO_OPC_MINIH, TILEPRO_OPC_MTSPR, CHILD(908),
+  TILEPRO_OPC_SEQIB, TILEPRO_OPC_SEQIH, TILEPRO_OPC_SEQI, TILEPRO_OPC_SLTIB,
   BITFIELD(37, 2) /* index 908 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(913),
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(913),
   BITFIELD(39, 2) /* index 913 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(918),
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(918),
   BITFIELD(41, 2) /* index 918 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_MOVEI,
   BITFIELD(51, 3) /* index 923 */,
-  TILE_OPC_SLTIB_U, TILE_OPC_SLTIH, TILE_OPC_SLTIH_U, TILE_OPC_SLTI,
-  TILE_OPC_SLTI_U, TILE_OPC_XORI, TILE_OPC_LBADD, TILE_OPC_LBADD_U,
+  TILEPRO_OPC_SLTIB_U, TILEPRO_OPC_SLTIH, TILEPRO_OPC_SLTIH_U,
+  TILEPRO_OPC_SLTI, TILEPRO_OPC_SLTI_U, TILEPRO_OPC_XORI, TILEPRO_OPC_LBADD,
+  TILEPRO_OPC_LBADD_U,
   BITFIELD(51, 3) /* index 932 */,
-  TILE_OPC_LHADD, TILE_OPC_LHADD_U, TILE_OPC_LWADD, TILE_OPC_LWADD_NA,
-  TILE_OPC_SBADD, TILE_OPC_SHADD, TILE_OPC_SWADD, TILE_OPC_NONE,
+  TILEPRO_OPC_LHADD, TILEPRO_OPC_LHADD_U, TILEPRO_OPC_LWADD,
+  TILEPRO_OPC_LWADD_NA, TILEPRO_OPC_SBADD, TILEPRO_OPC_SHADD,
+  TILEPRO_OPC_SWADD, TILEPRO_OPC_NONE,
   BITFIELD(51, 3) /* index 941 */,
-  TILE_OPC_NONE, TILE_OPC_ADDIB_SN, TILE_OPC_ADDIH_SN, TILE_OPC_ADDI_SN,
-  TILE_OPC_ANDI_SN, TILE_OPC_MAXIB_U_SN, TILE_OPC_MAXIH_SN, TILE_OPC_MFSPR,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_ADDIB_SN, TILEPRO_OPC_ADDIH_SN,
+  TILEPRO_OPC_ADDI_SN, TILEPRO_OPC_ANDI_SN, TILEPRO_OPC_MAXIB_U_SN,
+  TILEPRO_OPC_MAXIH_SN, TILEPRO_OPC_MFSPR,
   BITFIELD(51, 3) /* index 950 */,
-  TILE_OPC_MINIB_U_SN, TILE_OPC_MINIH_SN, TILE_OPC_MTSPR, CHILD(959),
-  TILE_OPC_SEQIB_SN, TILE_OPC_SEQIH_SN, TILE_OPC_SEQI_SN, TILE_OPC_SLTIB_SN,
+  TILEPRO_OPC_MINIB_U_SN, TILEPRO_OPC_MINIH_SN, TILEPRO_OPC_MTSPR, CHILD(959),
+  TILEPRO_OPC_SEQIB_SN, TILEPRO_OPC_SEQIH_SN, TILEPRO_OPC_SEQI_SN,
+  TILEPRO_OPC_SLTIB_SN,
   BITFIELD(37, 2) /* index 959 */,
-  TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(964),
+  TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, CHILD(964),
   BITFIELD(39, 2) /* index 964 */,
-  TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(969),
+  TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, CHILD(969),
   BITFIELD(41, 2) /* index 969 */,
-  TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_MOVEI_SN,
+  TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN, TILEPRO_OPC_ORI_SN,
+  TILEPRO_OPC_MOVEI_SN,
   BITFIELD(51, 3) /* index 974 */,
-  TILE_OPC_SLTIB_U_SN, TILE_OPC_SLTIH_SN, TILE_OPC_SLTIH_U_SN,
-  TILE_OPC_SLTI_SN, TILE_OPC_SLTI_U_SN, TILE_OPC_XORI_SN, TILE_OPC_LBADD_SN,
-  TILE_OPC_LBADD_U_SN,
+  TILEPRO_OPC_SLTIB_U_SN, TILEPRO_OPC_SLTIH_SN, TILEPRO_OPC_SLTIH_U_SN,
+  TILEPRO_OPC_SLTI_SN, TILEPRO_OPC_SLTI_U_SN, TILEPRO_OPC_XORI_SN,
+  TILEPRO_OPC_LBADD_SN, TILEPRO_OPC_LBADD_U_SN,
   BITFIELD(51, 3) /* index 983 */,
-  TILE_OPC_LHADD_SN, TILE_OPC_LHADD_U_SN, TILE_OPC_LWADD_SN,
-  TILE_OPC_LWADD_NA_SN, TILE_OPC_SBADD, TILE_OPC_SHADD, TILE_OPC_SWADD,
-  TILE_OPC_NONE,
+  TILEPRO_OPC_LHADD_SN, TILEPRO_OPC_LHADD_U_SN, TILEPRO_OPC_LWADD_SN,
+  TILEPRO_OPC_LWADD_NA_SN, TILEPRO_OPC_SBADD, TILEPRO_OPC_SHADD,
+  TILEPRO_OPC_SWADD, TILEPRO_OPC_NONE,
   BITFIELD(46, 7) /* index 992 */,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(1121),
-  CHILD(1121), CHILD(1121), CHILD(1121), CHILD(1124), CHILD(1124),
-  CHILD(1124), CHILD(1124), CHILD(1127), CHILD(1127), CHILD(1127),
-  CHILD(1127), CHILD(1130), CHILD(1130), CHILD(1130), CHILD(1130),
-  CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1136),
-  CHILD(1136), CHILD(1136), CHILD(1136), CHILD(1139), CHILD(1139),
-  CHILD(1139), CHILD(1139), CHILD(1142), CHILD(1142), CHILD(1142),
-  CHILD(1142), CHILD(1145), CHILD(1145), CHILD(1145), CHILD(1145),
-  CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1151),
-  CHILD(1242), CHILD(1290), CHILD(1323), TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  CHILD(1121), CHILD(1121), CHILD(1121), CHILD(1121), CHILD(1124),
+  CHILD(1124), CHILD(1124), CHILD(1124), CHILD(1127), CHILD(1127),
+  CHILD(1127), CHILD(1127), CHILD(1130), CHILD(1130), CHILD(1130),
+  CHILD(1130), CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1133),
+  CHILD(1136), CHILD(1136), CHILD(1136), CHILD(1136), CHILD(1139),
+  CHILD(1139), CHILD(1139), CHILD(1139), CHILD(1142), CHILD(1142),
+  CHILD(1142), CHILD(1142), CHILD(1145), CHILD(1145), CHILD(1145),
+  CHILD(1145), CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1148),
+  CHILD(1151), CHILD(1242), CHILD(1290), CHILD(1323), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1121 */,
-  TILE_OPC_RLI, TILE_OPC_NONE,
+  TILEPRO_OPC_RLI, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1124 */,
-  TILE_OPC_SHLIB, TILE_OPC_NONE,
+  TILEPRO_OPC_SHLIB, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1127 */,
-  TILE_OPC_SHLIH, TILE_OPC_NONE,
+  TILEPRO_OPC_SHLIH, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1130 */,
-  TILE_OPC_SHLI, TILE_OPC_NONE,
+  TILEPRO_OPC_SHLI, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1133 */,
-  TILE_OPC_SHRIB, TILE_OPC_NONE,
+  TILEPRO_OPC_SHRIB, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1136 */,
-  TILE_OPC_SHRIH, TILE_OPC_NONE,
+  TILEPRO_OPC_SHRIH, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1139 */,
-  TILE_OPC_SHRI, TILE_OPC_NONE,
+  TILEPRO_OPC_SHRI, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1142 */,
-  TILE_OPC_SRAIB, TILE_OPC_NONE,
+  TILEPRO_OPC_SRAIB, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1145 */,
-  TILE_OPC_SRAIH, TILE_OPC_NONE,
+  TILEPRO_OPC_SRAIH, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1148 */,
-  TILE_OPC_SRAI, TILE_OPC_NONE,
+  TILEPRO_OPC_SRAI, TILEPRO_OPC_NONE,
   BITFIELD(43, 3) /* index 1151 */,
-  TILE_OPC_NONE, CHILD(1160), CHILD(1163), CHILD(1166), CHILD(1169),
+  TILEPRO_OPC_NONE, CHILD(1160), CHILD(1163), CHILD(1166), CHILD(1169),
   CHILD(1172), CHILD(1175), CHILD(1178),
   BITFIELD(53, 1) /* index 1160 */,
-  TILE_OPC_DRAIN, TILE_OPC_NONE,
+  TILEPRO_OPC_DRAIN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1163 */,
-  TILE_OPC_DTLBPR, TILE_OPC_NONE,
+  TILEPRO_OPC_DTLBPR, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1166 */,
-  TILE_OPC_FINV, TILE_OPC_NONE,
+  TILEPRO_OPC_FINV, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1169 */,
-  TILE_OPC_FLUSH, TILE_OPC_NONE,
+  TILEPRO_OPC_FLUSH, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1172 */,
-  TILE_OPC_FNOP, TILE_OPC_NONE,
+  TILEPRO_OPC_FNOP, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1175 */,
-  TILE_OPC_ICOH, TILE_OPC_NONE,
+  TILEPRO_OPC_ICOH, TILEPRO_OPC_NONE,
   BITFIELD(31, 2) /* index 1178 */,
   CHILD(1183), CHILD(1211), CHILD(1239), CHILD(1239),
   BITFIELD(53, 1) /* index 1183 */,
-  CHILD(1186), TILE_OPC_NONE,
+  CHILD(1186), TILEPRO_OPC_NONE,
   BITFIELD(33, 2) /* index 1186 */,
-  TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_ILL, CHILD(1191),
+  TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, CHILD(1191),
   BITFIELD(35, 2) /* index 1191 */,
-  TILE_OPC_ILL, CHILD(1196), TILE_OPC_ILL, TILE_OPC_ILL,
+  TILEPRO_OPC_ILL, CHILD(1196), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
   BITFIELD(37, 2) /* index 1196 */,
-  TILE_OPC_ILL, CHILD(1201), TILE_OPC_ILL, TILE_OPC_ILL,
+  TILEPRO_OPC_ILL, CHILD(1201), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
   BITFIELD(39, 2) /* index 1201 */,
-  TILE_OPC_ILL, CHILD(1206), TILE_OPC_ILL, TILE_OPC_ILL,
+  TILEPRO_OPC_ILL, CHILD(1206), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
   BITFIELD(41, 2) /* index 1206 */,
-  TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_BPT, TILE_OPC_ILL,
+  TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, TILEPRO_OPC_BPT, TILEPRO_OPC_ILL,
   BITFIELD(53, 1) /* index 1211 */,
-  CHILD(1214), TILE_OPC_NONE,
+  CHILD(1214), TILEPRO_OPC_NONE,
   BITFIELD(33, 2) /* index 1214 */,
-  TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_ILL, CHILD(1219),
+  TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, CHILD(1219),
   BITFIELD(35, 2) /* index 1219 */,
-  TILE_OPC_ILL, CHILD(1224), TILE_OPC_ILL, TILE_OPC_ILL,
+  TILEPRO_OPC_ILL, CHILD(1224), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
   BITFIELD(37, 2) /* index 1224 */,
-  TILE_OPC_ILL, CHILD(1229), TILE_OPC_ILL, TILE_OPC_ILL,
+  TILEPRO_OPC_ILL, CHILD(1229), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
   BITFIELD(39, 2) /* index 1229 */,
-  TILE_OPC_ILL, CHILD(1234), TILE_OPC_ILL, TILE_OPC_ILL,
+  TILEPRO_OPC_ILL, CHILD(1234), TILEPRO_OPC_ILL, TILEPRO_OPC_ILL,
   BITFIELD(41, 2) /* index 1234 */,
-  TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_RAISE, TILE_OPC_ILL,
+  TILEPRO_OPC_ILL, TILEPRO_OPC_ILL, TILEPRO_OPC_RAISE, TILEPRO_OPC_ILL,
   BITFIELD(53, 1) /* index 1239 */,
-  TILE_OPC_ILL, TILE_OPC_NONE,
+  TILEPRO_OPC_ILL, TILEPRO_OPC_NONE,
   BITFIELD(43, 3) /* index 1242 */,
   CHILD(1251), CHILD(1254), CHILD(1257), CHILD(1275), CHILD(1278),
   CHILD(1281), CHILD(1284), CHILD(1287),
   BITFIELD(53, 1) /* index 1251 */,
-  TILE_OPC_INV, TILE_OPC_NONE,
+  TILEPRO_OPC_INV, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1254 */,
-  TILE_OPC_IRET, TILE_OPC_NONE,
+  TILEPRO_OPC_IRET, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1257 */,
-  CHILD(1260), TILE_OPC_NONE,
+  CHILD(1260), TILEPRO_OPC_NONE,
   BITFIELD(31, 2) /* index 1260 */,
-  TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(1265),
+  TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, CHILD(1265),
   BITFIELD(33, 2) /* index 1265 */,
-  TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(1270),
+  TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, CHILD(1270),
   BITFIELD(35, 2) /* index 1270 */,
-  TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_PREFETCH,
+  TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_PREFETCH,
   BITFIELD(53, 1) /* index 1275 */,
-  TILE_OPC_LB_U, TILE_OPC_NONE,
+  TILEPRO_OPC_LB_U, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1278 */,
-  TILE_OPC_LH, TILE_OPC_NONE,
+  TILEPRO_OPC_LH, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1281 */,
-  TILE_OPC_LH_U, TILE_OPC_NONE,
+  TILEPRO_OPC_LH_U, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1284 */,
-  TILE_OPC_LW, TILE_OPC_NONE,
+  TILEPRO_OPC_LW, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1287 */,
-  TILE_OPC_MF, TILE_OPC_NONE,
+  TILEPRO_OPC_MF, TILEPRO_OPC_NONE,
   BITFIELD(43, 3) /* index 1290 */,
   CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311),
   CHILD(1314), CHILD(1317), CHILD(1320),
   BITFIELD(53, 1) /* index 1299 */,
-  TILE_OPC_NAP, TILE_OPC_NONE,
+  TILEPRO_OPC_NAP, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1302 */,
-  TILE_OPC_NOP, TILE_OPC_NONE,
+  TILEPRO_OPC_NOP, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1305 */,
-  TILE_OPC_SWINT0, TILE_OPC_NONE,
+  TILEPRO_OPC_SWINT0, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1308 */,
-  TILE_OPC_SWINT1, TILE_OPC_NONE,
+  TILEPRO_OPC_SWINT1, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1311 */,
-  TILE_OPC_SWINT2, TILE_OPC_NONE,
+  TILEPRO_OPC_SWINT2, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1314 */,
-  TILE_OPC_SWINT3, TILE_OPC_NONE,
+  TILEPRO_OPC_SWINT3, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1317 */,
-  TILE_OPC_TNS, TILE_OPC_NONE,
+  TILEPRO_OPC_TNS, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1320 */,
-  TILE_OPC_WH64, TILE_OPC_NONE,
+  TILEPRO_OPC_WH64, TILEPRO_OPC_NONE,
   BITFIELD(43, 2) /* index 1323 */,
-  CHILD(1328), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  CHILD(1328), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(45, 1) /* index 1328 */,
-  CHILD(1331), TILE_OPC_NONE,
+  CHILD(1331), TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1331 */,
-  TILE_OPC_LW_NA, TILE_OPC_NONE,
+  TILEPRO_OPC_LW_NA, TILEPRO_OPC_NONE,
   BITFIELD(46, 7) /* index 1334 */,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(1463),
-  CHILD(1463), CHILD(1463), CHILD(1463), CHILD(1466), CHILD(1466),
-  CHILD(1466), CHILD(1466), CHILD(1469), CHILD(1469), CHILD(1469),
-  CHILD(1469), CHILD(1472), CHILD(1472), CHILD(1472), CHILD(1472),
-  CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1478),
-  CHILD(1478), CHILD(1478), CHILD(1478), CHILD(1481), CHILD(1481),
-  CHILD(1481), CHILD(1481), CHILD(1484), CHILD(1484), CHILD(1484),
-  CHILD(1484), CHILD(1487), CHILD(1487), CHILD(1487), CHILD(1487),
-  CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1151),
-  CHILD(1493), CHILD(1517), CHILD(1529), TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  CHILD(1463), CHILD(1463), CHILD(1463), CHILD(1463), CHILD(1466),
+  CHILD(1466), CHILD(1466), CHILD(1466), CHILD(1469), CHILD(1469),
+  CHILD(1469), CHILD(1469), CHILD(1472), CHILD(1472), CHILD(1472),
+  CHILD(1472), CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1475),
+  CHILD(1478), CHILD(1478), CHILD(1478), CHILD(1478), CHILD(1481),
+  CHILD(1481), CHILD(1481), CHILD(1481), CHILD(1484), CHILD(1484),
+  CHILD(1484), CHILD(1484), CHILD(1487), CHILD(1487), CHILD(1487),
+  CHILD(1487), CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1490),
+  CHILD(1151), CHILD(1493), CHILD(1517), CHILD(1529), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1463 */,
-  TILE_OPC_RLI_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_RLI_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1466 */,
-  TILE_OPC_SHLIB_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SHLIB_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1469 */,
-  TILE_OPC_SHLIH_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SHLIH_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1472 */,
-  TILE_OPC_SHLI_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SHLI_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1475 */,
-  TILE_OPC_SHRIB_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SHRIB_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1478 */,
-  TILE_OPC_SHRIH_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SHRIH_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1481 */,
-  TILE_OPC_SHRI_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SHRI_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1484 */,
-  TILE_OPC_SRAIB_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SRAIB_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1487 */,
-  TILE_OPC_SRAIH_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SRAIH_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1490 */,
-  TILE_OPC_SRAI_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_SRAI_SN, TILEPRO_OPC_NONE,
   BITFIELD(43, 3) /* index 1493 */,
   CHILD(1251), CHILD(1254), CHILD(1502), CHILD(1505), CHILD(1508),
   CHILD(1511), CHILD(1514), CHILD(1287),
   BITFIELD(53, 1) /* index 1502 */,
-  TILE_OPC_LB_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_LB_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1505 */,
-  TILE_OPC_LB_U_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_LB_U_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1508 */,
-  TILE_OPC_LH_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_LH_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1511 */,
-  TILE_OPC_LH_U_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_LH_U_SN, TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1514 */,
-  TILE_OPC_LW_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_LW_SN, TILEPRO_OPC_NONE,
   BITFIELD(43, 3) /* index 1517 */,
   CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311),
   CHILD(1314), CHILD(1526), CHILD(1320),
   BITFIELD(53, 1) /* index 1526 */,
-  TILE_OPC_TNS_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_TNS_SN, TILEPRO_OPC_NONE,
   BITFIELD(43, 2) /* index 1529 */,
-  CHILD(1534), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  CHILD(1534), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(45, 1) /* index 1534 */,
-  CHILD(1537), TILE_OPC_NONE,
+  CHILD(1537), TILEPRO_OPC_NONE,
   BITFIELD(53, 1) /* index 1537 */,
-  TILE_OPC_LW_NA_SN, TILE_OPC_NONE,
+  TILEPRO_OPC_LW_NA_SN, TILEPRO_OPC_NONE,
 };
 
 static const unsigned short decode_Y0_fsm[168] =
 {
   BITFIELD(27, 4) /* index 0 */,
-  TILE_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
-  CHILD(57), CHILD(62), CHILD(67), TILE_OPC_ADDI, CHILD(72), CHILD(102),
-  TILE_OPC_SEQI, CHILD(117), TILE_OPC_SLTI, TILE_OPC_SLTI_U,
+  TILEPRO_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
+  CHILD(57), CHILD(62), CHILD(67), TILEPRO_OPC_ADDI, CHILD(72), CHILD(102),
+  TILEPRO_OPC_SEQI, CHILD(117), TILEPRO_OPC_SLTI, TILEPRO_OPC_SLTI_U,
   BITFIELD(18, 2) /* index 17 */,
-  TILE_OPC_ADD, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_SUB,
+  TILEPRO_OPC_ADD, TILEPRO_OPC_S1A, TILEPRO_OPC_S2A, TILEPRO_OPC_SUB,
   BITFIELD(18, 2) /* index 22 */,
-  TILE_OPC_MNZ, TILE_OPC_MVNZ, TILE_OPC_MVZ, TILE_OPC_MZ,
+  TILEPRO_OPC_MNZ, TILEPRO_OPC_MVNZ, TILEPRO_OPC_MVZ, TILEPRO_OPC_MZ,
   BITFIELD(18, 2) /* index 27 */,
-  TILE_OPC_AND, TILE_OPC_NOR, CHILD(32), TILE_OPC_XOR,
+  TILEPRO_OPC_AND, TILEPRO_OPC_NOR, CHILD(32), TILEPRO_OPC_XOR,
   BITFIELD(12, 2) /* index 32 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(37),
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(37),
   BITFIELD(14, 2) /* index 37 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(42),
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(42),
   BITFIELD(16, 2) /* index 42 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_MOVE,
   BITFIELD(18, 2) /* index 47 */,
-  TILE_OPC_RL, TILE_OPC_SHL, TILE_OPC_SHR, TILE_OPC_SRA,
+  TILEPRO_OPC_RL, TILEPRO_OPC_SHL, TILEPRO_OPC_SHR, TILEPRO_OPC_SRA,
   BITFIELD(18, 2) /* index 52 */,
-  TILE_OPC_SLTE, TILE_OPC_SLTE_U, TILE_OPC_SLT, TILE_OPC_SLT_U,
+  TILEPRO_OPC_SLTE, TILEPRO_OPC_SLTE_U, TILEPRO_OPC_SLT, TILEPRO_OPC_SLT_U,
   BITFIELD(18, 2) /* index 57 */,
-  TILE_OPC_MULHLSA_UU, TILE_OPC_S3A, TILE_OPC_SEQ, TILE_OPC_SNE,
+  TILEPRO_OPC_MULHLSA_UU, TILEPRO_OPC_S3A, TILEPRO_OPC_SEQ, TILEPRO_OPC_SNE,
   BITFIELD(18, 2) /* index 62 */,
-  TILE_OPC_MULHH_SS, TILE_OPC_MULHH_UU, TILE_OPC_MULLL_SS, TILE_OPC_MULLL_UU,
+  TILEPRO_OPC_MULHH_SS, TILEPRO_OPC_MULHH_UU, TILEPRO_OPC_MULLL_SS,
+  TILEPRO_OPC_MULLL_UU,
   BITFIELD(18, 2) /* index 67 */,
-  TILE_OPC_MULHHA_SS, TILE_OPC_MULHHA_UU, TILE_OPC_MULLLA_SS,
-  TILE_OPC_MULLLA_UU,
+  TILEPRO_OPC_MULHHA_SS, TILEPRO_OPC_MULHHA_UU, TILEPRO_OPC_MULLLA_SS,
+  TILEPRO_OPC_MULLLA_UU,
   BITFIELD(0, 2) /* index 72 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(77),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(77),
   BITFIELD(2, 2) /* index 77 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(82),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(82),
   BITFIELD(4, 2) /* index 82 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(87),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(87),
   BITFIELD(6, 2) /* index 87 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(92),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(92),
   BITFIELD(8, 2) /* index 92 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(97),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(97),
   BITFIELD(10, 2) /* index 97 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_INFO,
   BITFIELD(6, 2) /* index 102 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(107),
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(107),
   BITFIELD(8, 2) /* index 107 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(112),
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(112),
   BITFIELD(10, 2) /* index 112 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_MOVEI,
   BITFIELD(15, 5) /* index 117 */,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_RLI,
-  TILE_OPC_RLI, TILE_OPC_RLI, TILE_OPC_RLI, TILE_OPC_SHLI, TILE_OPC_SHLI,
-  TILE_OPC_SHLI, TILE_OPC_SHLI, TILE_OPC_SHRI, TILE_OPC_SHRI, TILE_OPC_SHRI,
-  TILE_OPC_SHRI, TILE_OPC_SRAI, TILE_OPC_SRAI, TILE_OPC_SRAI, TILE_OPC_SRAI,
-  CHILD(150), CHILD(159), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_RLI, TILEPRO_OPC_RLI, TILEPRO_OPC_RLI, TILEPRO_OPC_RLI,
+  TILEPRO_OPC_SHLI, TILEPRO_OPC_SHLI, TILEPRO_OPC_SHLI, TILEPRO_OPC_SHLI,
+  TILEPRO_OPC_SHRI, TILEPRO_OPC_SHRI, TILEPRO_OPC_SHRI, TILEPRO_OPC_SHRI,
+  TILEPRO_OPC_SRAI, TILEPRO_OPC_SRAI, TILEPRO_OPC_SRAI, TILEPRO_OPC_SRAI,
+  CHILD(150), CHILD(159), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(12, 3) /* index 150 */,
-  TILE_OPC_NONE, TILE_OPC_BITX, TILE_OPC_BYTEX, TILE_OPC_CLZ, TILE_OPC_CTZ,
-  TILE_OPC_FNOP, TILE_OPC_NOP, TILE_OPC_PCNT,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_BITX, TILEPRO_OPC_BYTEX, TILEPRO_OPC_CLZ,
+  TILEPRO_OPC_CTZ, TILEPRO_OPC_FNOP, TILEPRO_OPC_NOP, TILEPRO_OPC_PCNT,
   BITFIELD(12, 3) /* index 159 */,
-  TILE_OPC_TBLIDXB0, TILE_OPC_TBLIDXB1, TILE_OPC_TBLIDXB2, TILE_OPC_TBLIDXB3,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_TBLIDXB0, TILEPRO_OPC_TBLIDXB1, TILEPRO_OPC_TBLIDXB2,
+  TILEPRO_OPC_TBLIDXB3, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE,
 };
 
 static const unsigned short decode_Y1_fsm[140] =
 {
   BITFIELD(59, 4) /* index 0 */,
-  TILE_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
-  CHILD(57), TILE_OPC_ADDI, CHILD(62), CHILD(92), TILE_OPC_SEQI, CHILD(107),
-  TILE_OPC_SLTI, TILE_OPC_SLTI_U, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
+  CHILD(57), TILEPRO_OPC_ADDI, CHILD(62), CHILD(92), TILEPRO_OPC_SEQI,
+  CHILD(107), TILEPRO_OPC_SLTI, TILEPRO_OPC_SLTI_U, TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE,
   BITFIELD(49, 2) /* index 17 */,
-  TILE_OPC_ADD, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_SUB,
+  TILEPRO_OPC_ADD, TILEPRO_OPC_S1A, TILEPRO_OPC_S2A, TILEPRO_OPC_SUB,
   BITFIELD(49, 2) /* index 22 */,
-  TILE_OPC_NONE, TILE_OPC_MNZ, TILE_OPC_MZ, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_MNZ, TILEPRO_OPC_MZ, TILEPRO_OPC_NONE,
   BITFIELD(49, 2) /* index 27 */,
-  TILE_OPC_AND, TILE_OPC_NOR, CHILD(32), TILE_OPC_XOR,
+  TILEPRO_OPC_AND, TILEPRO_OPC_NOR, CHILD(32), TILEPRO_OPC_XOR,
   BITFIELD(43, 2) /* index 32 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(37),
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(37),
   BITFIELD(45, 2) /* index 37 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(42),
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, CHILD(42),
   BITFIELD(47, 2) /* index 42 */,
-  TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
+  TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_OR, TILEPRO_OPC_MOVE,
   BITFIELD(49, 2) /* index 47 */,
-  TILE_OPC_RL, TILE_OPC_SHL, TILE_OPC_SHR, TILE_OPC_SRA,
+  TILEPRO_OPC_RL, TILEPRO_OPC_SHL, TILEPRO_OPC_SHR, TILEPRO_OPC_SRA,
   BITFIELD(49, 2) /* index 52 */,
-  TILE_OPC_SLTE, TILE_OPC_SLTE_U, TILE_OPC_SLT, TILE_OPC_SLT_U,
+  TILEPRO_OPC_SLTE, TILEPRO_OPC_SLTE_U, TILEPRO_OPC_SLT, TILEPRO_OPC_SLT_U,
   BITFIELD(49, 2) /* index 57 */,
-  TILE_OPC_NONE, TILE_OPC_S3A, TILE_OPC_SEQ, TILE_OPC_SNE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_S3A, TILEPRO_OPC_SEQ, TILEPRO_OPC_SNE,
   BITFIELD(31, 2) /* index 62 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(67),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(67),
   BITFIELD(33, 2) /* index 67 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(72),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(72),
   BITFIELD(35, 2) /* index 72 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(77),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(77),
   BITFIELD(37, 2) /* index 77 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(82),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(82),
   BITFIELD(39, 2) /* index 82 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(87),
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, CHILD(87),
   BITFIELD(41, 2) /* index 87 */,
-  TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
+  TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_ANDI, TILEPRO_OPC_INFO,
   BITFIELD(37, 2) /* index 92 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(97),
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(97),
   BITFIELD(39, 2) /* index 97 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(102),
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, CHILD(102),
   BITFIELD(41, 2) /* index 102 */,
-  TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
+  TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_ORI, TILEPRO_OPC_MOVEI,
   BITFIELD(48, 3) /* index 107 */,
-  TILE_OPC_NONE, TILE_OPC_RLI, TILE_OPC_SHLI, TILE_OPC_SHRI, TILE_OPC_SRAI,
-  CHILD(116), TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_RLI, TILEPRO_OPC_SHLI, TILEPRO_OPC_SHRI,
+  TILEPRO_OPC_SRAI, CHILD(116), TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(43, 3) /* index 116 */,
-  TILE_OPC_NONE, CHILD(125), CHILD(130), CHILD(135), TILE_OPC_NONE,
-  TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_NONE, CHILD(125), CHILD(130), CHILD(135), TILEPRO_OPC_NONE,
+  TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(46, 2) /* index 125 */,
-  TILE_OPC_FNOP, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_FNOP, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(46, 2) /* index 130 */,
-  TILE_OPC_ILL, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_ILL, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
   BITFIELD(46, 2) /* index 135 */,
-  TILE_OPC_NOP, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+  TILEPRO_OPC_NOP, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE, TILEPRO_OPC_NONE,
 };
 
 static const unsigned short decode_Y2_fsm[24] =
 {
   BITFIELD(56, 3) /* index 0 */,
-  CHILD(9), TILE_OPC_LB_U, TILE_OPC_LH, TILE_OPC_LH_U, TILE_OPC_LW,
-  TILE_OPC_SB, TILE_OPC_SH, TILE_OPC_SW,
+  CHILD(9), TILEPRO_OPC_LB_U, TILEPRO_OPC_LH, TILEPRO_OPC_LH_U,
+  TILEPRO_OPC_LW, TILEPRO_OPC_SB, TILEPRO_OPC_SH, TILEPRO_OPC_SW,
   BITFIELD(20, 2) /* index 9 */,
-  TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(14),
+  TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, CHILD(14),
   BITFIELD(22, 2) /* index 14 */,
-  TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(19),
+  TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, CHILD(19),
   BITFIELD(24, 2) /* index 19 */,
-  TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_PREFETCH,
+  TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_LB, TILEPRO_OPC_PREFETCH,
 };
 
 #undef BITFIELD
 #undef CHILD
 const unsigned short * const
-tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS] =
+tilepro_bundle_decoder_fsms[TILEPRO_NUM_PIPELINE_ENCODINGS] =
 {
   decode_X0_fsm,
   decode_X1_fsm,
@@ -2191,220 +2297,220 @@ tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS] =
   decode_Y1_fsm,
   decode_Y2_fsm
 };
-const struct tile_operand tile_operands[43] =
+const struct tilepro_operand tilepro_operands[43] =
 {
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_X0),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM8_X0),
     8, 1, 0, 0, 0, 0,
     create_Imm8_X0, get_Imm8_X0
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_X1),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM8_X1),
     8, 1, 0, 0, 0, 0,
     create_Imm8_X1, get_Imm8_X1
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_Y0),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM8_Y0),
     8, 1, 0, 0, 0, 0,
     create_Imm8_Y0, get_Imm8_Y0
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_Y1),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM8_Y1),
     8, 1, 0, 0, 0, 0,
     create_Imm8_Y1, get_Imm8_Y1
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM16_X0),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM16_X0),
     16, 1, 0, 0, 0, 0,
     create_Imm16_X0, get_Imm16_X0
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM16_X1),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_IMM16_X1),
     16, 1, 0, 0, 0, 0,
     create_Imm16_X1, get_Imm16_X1
   },
   {
-    TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_JOFFLONG_X1),
-    29, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+    TILEPRO_OP_TYPE_ADDRESS, BFD_RELOC(TILEPRO_JOFFLONG_X1),
+    29, 1, 0, 0, 1, TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
     create_JOffLong_X1, get_JOffLong_X1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 0, 1, 0, 0,
     create_Dest_X0, get_Dest_X0
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcA_X0, get_SrcA_X0
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 0, 1, 0, 0,
     create_Dest_X1, get_Dest_X1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcA_X1, get_SrcA_X1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 0, 1, 0, 0,
     create_Dest_Y0, get_Dest_Y0
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcA_Y0, get_SrcA_Y0
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 0, 1, 0, 0,
     create_Dest_Y1, get_Dest_Y1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcA_Y1, get_SrcA_Y1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcA_Y2, get_SrcA_Y2
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcB_X0, get_SrcB_X0
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcB_X1, get_SrcB_X1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcB_Y0, get_SrcB_Y0
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcB_Y1, get_SrcB_Y1
   },
   {
-    TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_BROFF_X1),
-    17, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+    TILEPRO_OP_TYPE_ADDRESS, BFD_RELOC(TILEPRO_BROFF_X1),
+    17, 1, 0, 0, 1, TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
     create_BrOff_X1, get_BrOff_X1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 1, 0, 0,
     create_Dest_X0, get_Dest_X0
   },
   {
-    TILE_OP_TYPE_ADDRESS, BFD_RELOC(NONE),
-    28, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+    TILEPRO_OP_TYPE_ADDRESS, BFD_RELOC(NONE),
+    28, 1, 0, 0, 1, TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
     create_JOff_X1, get_JOff_X1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 0, 1, 0, 0,
     create_SrcBDest_Y2, get_SrcBDest_Y2
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 1, 0, 0,
     create_SrcA_X1, get_SrcA_X1
   },
   {
-    TILE_OP_TYPE_SPR, BFD_RELOC(TILE_MF_IMM15_X1),
+    TILEPRO_OP_TYPE_SPR, BFD_RELOC(TILEPRO_MF_IMM15_X1),
     15, 0, 0, 0, 0, 0,
     create_MF_Imm15_X1, get_MF_Imm15_X1
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMSTART_X0),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_MMSTART_X0),
     5, 0, 0, 0, 0, 0,
     create_MMStart_X0, get_MMStart_X0
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMEND_X0),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_MMEND_X0),
     5, 0, 0, 0, 0, 0,
     create_MMEnd_X0, get_MMEnd_X0
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMSTART_X1),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_MMSTART_X1),
     5, 0, 0, 0, 0, 0,
     create_MMStart_X1, get_MMStart_X1
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMEND_X1),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_MMEND_X1),
     5, 0, 0, 0, 0, 0,
     create_MMEnd_X1, get_MMEnd_X1
   },
   {
-    TILE_OP_TYPE_SPR, BFD_RELOC(TILE_MT_IMM15_X1),
+    TILEPRO_OP_TYPE_SPR, BFD_RELOC(TILEPRO_MT_IMM15_X1),
     15, 0, 0, 0, 0, 0,
     create_MT_Imm15_X1, get_MT_Imm15_X1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 1, 0, 0,
     create_Dest_Y0, get_Dest_Y0
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_X0),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_SHAMT_X0),
     5, 0, 0, 0, 0, 0,
     create_ShAmt_X0, get_ShAmt_X0
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_X1),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_SHAMT_X1),
     5, 0, 0, 0, 0, 0,
     create_ShAmt_X1, get_ShAmt_X1
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_Y0),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_SHAMT_Y0),
     5, 0, 0, 0, 0, 0,
     create_ShAmt_Y0, get_ShAmt_Y0
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_Y1),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_SHAMT_Y1),
     5, 0, 0, 0, 0, 0,
     create_ShAmt_Y1, get_ShAmt_Y1
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     6, 0, 1, 0, 0, 0,
     create_SrcBDest_Y2, get_SrcBDest_Y2
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEPRO_DEST_IMM8_X1),
     8, 1, 0, 0, 0, 0,
     create_Dest_Imm8_X1, get_Dest_Imm8_X1
   },
   {
-    TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_SN_BROFF),
-    10, 1, 0, 0, 1, TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES,
+    TILEPRO_OP_TYPE_ADDRESS, BFD_RELOC(NONE),
+    10, 1, 0, 0, 1, TILEPRO_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES,
     create_BrOff_SN, get_BrOff_SN
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SN_UIMM8),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
     8, 0, 0, 0, 0, 0,
     create_Imm8_SN, get_Imm8_SN
   },
   {
-    TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SN_IMM8),
+    TILEPRO_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
     8, 1, 0, 0, 0, 0,
     create_Imm8_SN, get_Imm8_SN
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     2, 0, 0, 1, 0, 0,
     create_Dest_SN, get_Dest_SN
   },
   {
-    TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    TILEPRO_OP_TYPE_REGISTER, BFD_RELOC(NONE),
     2, 0, 1, 0, 0, 0,
     create_Src_SN, get_Src_SN
   }
@@ -2416,10 +2522,10 @@ const struct tile_operand tile_operands[43] =
 /* Given a set of bundle bits and a specific pipe, returns which
  * instruction the bundle contains in that pipe.
  */
-const struct tile_opcode *
-find_opcode(tile_bundle_bits bits, tile_pipeline pipe)
+const struct tilepro_opcode *
+find_opcode(tilepro_bundle_bits bits, tilepro_pipeline pipe)
 {
-  const unsigned short *table = tile_bundle_decoder_fsms[pipe];
+  const unsigned short *table = tilepro_bundle_decoder_fsms[pipe];
   int index = 0;
 
   while (1)
@@ -2429,51 +2535,51 @@ find_opcode(tile_bundle_bits bits, tile_pipeline pipe)
       ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6);
 
     unsigned short next = table[index + 1 + bitfield];
-    if (next <= TILE_OPC_NONE)
-      return &tile_opcodes[next];
+    if (next <= TILEPRO_OPC_NONE)
+      return &tilepro_opcodes[next];
 
-    index = next - TILE_OPC_NONE;
+    index = next - TILEPRO_OPC_NONE;
   }
 }
 
 
 int
-parse_insn_tile(tile_bundle_bits bits,
-                unsigned int pc,
-                struct tile_decoded_instruction
-                decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE])
+parse_insn_tilepro(tilepro_bundle_bits bits,
+                   unsigned int pc,
+                   struct tilepro_decoded_instruction
+                   decoded[TILEPRO_MAX_INSTRUCTIONS_PER_BUNDLE])
 {
   int num_instructions = 0;
   int pipe;
 
   int min_pipe, max_pipe;
-  if ((bits & TILE_BUNDLE_Y_ENCODING_MASK) == 0)
+  if ((bits & TILEPRO_BUNDLE_Y_ENCODING_MASK) == 0)
   {
-    min_pipe = TILE_PIPELINE_X0;
-    max_pipe = TILE_PIPELINE_X1;
+    min_pipe = TILEPRO_PIPELINE_X0;
+    max_pipe = TILEPRO_PIPELINE_X1;
   }
   else
   {
-    min_pipe = TILE_PIPELINE_Y0;
-    max_pipe = TILE_PIPELINE_Y2;
+    min_pipe = TILEPRO_PIPELINE_Y0;
+    max_pipe = TILEPRO_PIPELINE_Y2;
   }
 
   /* For each pipe, find an instruction that fits. */
   for (pipe = min_pipe; pipe <= max_pipe; pipe++)
   {
-    const struct tile_opcode *opc;
-    struct tile_decoded_instruction *d;
+    const struct tilepro_opcode *opc;
+    struct tilepro_decoded_instruction *d;
     int i;
 
     d = &decoded[num_instructions++];
-    opc = find_opcode (bits, (tile_pipeline)pipe);
+    opc = find_opcode (bits, (tilepro_pipeline)pipe);
     d->opcode = opc;
 
     /* Decode each operand, sign extending, etc. as appropriate. */
     for (i = 0; i < opc->num_operands; i++)
     {
-      const struct tile_operand *op =
-        &tile_operands[opc->operands[pipe][i]];
+      const struct tilepro_operand *op =
+        &tilepro_operands[opc->operands[pipe][i]];
       int opval = op->extract (bits);
       if (op->is_signed)
       {
@@ -2483,9 +2589,9 @@ parse_insn_tile(tile_bundle_bits bits,
       }
 
       /* Adjust PC-relative scaled branch offsets. */
-      if (op->type == TILE_OP_TYPE_ADDRESS)
+      if (op->type == TILEPRO_OP_TYPE_ADDRESS)
       {
-        opval *= TILE_BUNDLE_SIZE_IN_BYTES;
+        opval *= TILEPRO_BUNDLE_SIZE_IN_BYTES;
         opval += (int)pc;
       }
 
index d57007b..65b5f8a 100644 (file)
@@ -1,3 +1,23 @@
+/* TILE-Gx opcode information.
+ *
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ *
+ *
+ *
+ *
+ */
+
 /* This define is BFD_RELOC_##x for real bfd, or -1 for everyone else. */
 #define BFD_RELOC(x) -1
 
@@ -6,10 +26,8 @@
 #define TREG_SN 56
 #define TREG_ZERO 63
 
-/* FIXME: Rename this. */
-#include <asm/opcode-tile_64.h>
-
 #include <linux/stddef.h>
+#include <asm/tile-desc.h>
 
 const struct tilegx_opcode tilegx_opcodes[334] =
 {
@@ -2040,12 +2058,12 @@ const struct tilegx_operand tilegx_operands[35] =
     create_BrOff_X1, get_BrOff_X1
   },
   {
-    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0),
     6, 0, 0, 0, 0, 0,
     create_BFStart_X0, get_BFStart_X0
   },
   {
-    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0),
     6, 0, 0, 0, 0, 0,
     create_BFEnd_X0, get_BFEnd_X0
   },
index f9803df..4f47b8a 100644 (file)
 #include <linux/reboot.h>
 #include <linux/uaccess.h>
 #include <linux/ptrace.h>
-#include <asm/opcode-tile.h>
-#include <asm/opcode_constants.h>
 #include <asm/stack.h>
 #include <asm/traps.h>
 
 #include <arch/interrupts.h>
 #include <arch/spr_def.h>
+#include <arch/opcode.h>
 
 void __init trap_init(void)
 {
@@ -135,7 +134,7 @@ static int special_ill(bundle_bits bundle, int *sigp, int *codep)
        if (get_UnaryOpcodeExtension_X1(bundle) != ILL_UNARY_OPCODE_X1)
                return 0;
 #else
-       if (bundle & TILE_BUNDLE_Y_ENCODING_MASK)
+       if (bundle & TILEPRO_BUNDLE_Y_ENCODING_MASK)
                return 0;
        if (get_Opcode_X1(bundle) != SHUN_0_OPCODE_X1)
                return 0;
index 49284fa..a87d2a8 100644 (file)
@@ -79,8 +79,6 @@ EXPORT_SYMBOL(__umoddi3);
 int64_t __moddi3(int64_t dividend, int64_t divisor);
 EXPORT_SYMBOL(__moddi3);
 #ifndef __tilegx__
-uint64_t __ll_mul(uint64_t n0, uint64_t n1);
-EXPORT_SYMBOL(__ll_mul);
 int64_t __muldi3(int64_t, int64_t);
 EXPORT_SYMBOL(__muldi3);
 uint64_t __lshrdi3(uint64_t, unsigned int);
index c03277d..004f2ce 100644 (file)
@@ -202,11 +202,18 @@ static int __devexit ahci_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id ahci_of_match[] = {
+       { .compatible = "calxeda,hb-ahci", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ahci_of_match);
+
 static struct platform_driver ahci_driver = {
        .remove = __devexit_p(ahci_remove),
        .driver = {
                .name = "ahci",
                .owner = THIS_MODULE,
+               .of_match_table = ahci_of_match,
        },
        .id_table       = ahci_devtype,
 };
index 6815905..ddc2a13 100644 (file)
@@ -1307,6 +1307,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
            ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
                callback = descnew->txd.callback;
                callback_param = descnew->txd.callback_param;
+               list_del_init(&descnew->list);
                spin_unlock(&ichan->lock);
                if (callback)
                        callback(callback_param);
@@ -1428,39 +1429,58 @@ static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 {
        struct idmac_channel *ichan = to_idmac_chan(chan);
        struct idmac *idmac = to_idmac(chan->device);
+       struct ipu *ipu = to_ipu(idmac);
+       struct list_head *list, *tmp;
        unsigned long flags;
        int i;
 
-       /* Only supports DMA_TERMINATE_ALL */
-       if (cmd != DMA_TERMINATE_ALL)
-               return -ENXIO;
+       switch (cmd) {
+       case DMA_PAUSE:
+               spin_lock_irqsave(&ipu->lock, flags);
+               ipu_ic_disable_task(ipu, chan->chan_id);
 
-       ipu_disable_channel(idmac, ichan,
-                           ichan->status >= IPU_CHANNEL_ENABLED);
+               /* Return all descriptors into "prepared" state */
+               list_for_each_safe(list, tmp, &ichan->queue)
+                       list_del_init(list);
 
-       tasklet_disable(&to_ipu(idmac)->tasklet);
+               ichan->sg[0] = NULL;
+               ichan->sg[1] = NULL;
 
-       /* ichan->queue is modified in ISR, have to spinlock */
-       spin_lock_irqsave(&ichan->lock, flags);
-       list_splice_init(&ichan->queue, &ichan->free_list);
+               spin_unlock_irqrestore(&ipu->lock, flags);
 
-       if (ichan->desc)
-               for (i = 0; i < ichan->n_tx_desc; i++) {
-                       struct idmac_tx_desc *desc = ichan->desc + i;
-                       if (list_empty(&desc->list))
-                               /* Descriptor was prepared, but not submitted */
-                               list_add(&desc->list, &ichan->free_list);
+               ichan->status = IPU_CHANNEL_INITIALIZED;
+               break;
+       case DMA_TERMINATE_ALL:
+               ipu_disable_channel(idmac, ichan,
+                                   ichan->status >= IPU_CHANNEL_ENABLED);
 
-                       async_tx_clear_ack(&desc->txd);
-               }
+               tasklet_disable(&ipu->tasklet);
 
-       ichan->sg[0] = NULL;
-       ichan->sg[1] = NULL;
-       spin_unlock_irqrestore(&ichan->lock, flags);
+               /* ichan->queue is modified in ISR, have to spinlock */
+               spin_lock_irqsave(&ichan->lock, flags);
+               list_splice_init(&ichan->queue, &ichan->free_list);
 
-       tasklet_enable(&to_ipu(idmac)->tasklet);
+               if (ichan->desc)
+                       for (i = 0; i < ichan->n_tx_desc; i++) {
+                               struct idmac_tx_desc *desc = ichan->desc + i;
+                               if (list_empty(&desc->list))
+                                       /* Descriptor was prepared, but not submitted */
+                                       list_add(&desc->list, &ichan->free_list);
 
-       ichan->status = IPU_CHANNEL_INITIALIZED;
+                               async_tx_clear_ack(&desc->txd);
+                       }
+
+               ichan->sg[0] = NULL;
+               ichan->sg[1] = NULL;
+               spin_unlock_irqrestore(&ichan->lock, flags);
+
+               tasklet_enable(&ipu->tasklet);
+
+               ichan->status = IPU_CHANNEL_INITIALIZED;
+               break;
+       default:
+               return -ENOSYS;
+       }
 
        return 0;
 }
@@ -1663,7 +1683,6 @@ static void __exit ipu_idmac_exit(struct ipu *ipu)
                struct idmac_channel *ichan = ipu->channel + i;
 
                idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0);
-               idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0);
        }
 
        dma_async_device_unregister(&idmac->dma);
index 9b347ac..9ec854a 100644 (file)
@@ -335,6 +335,7 @@ config SENSORS_I5K_AMB
 
 config SENSORS_F71805F
        tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG"
+       depends on !PPC
        help
          If you say yes here you get support for hardware monitoring
          features of the Fintek F71805F/FG, F71806F/FG and F71872F/FG
@@ -345,6 +346,7 @@ config SENSORS_F71805F
 
 config SENSORS_F71882FG
        tristate "Fintek F71882FG and compatibles"
+       depends on !PPC
        help
          If you say yes here you get support for hardware monitoring
          features of many Fintek Super-I/O (LPC) chips. The currently
@@ -468,6 +470,7 @@ config SENSORS_IBMPEX
 
 config SENSORS_IT87
        tristate "ITE IT87xx and compatibles"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here you get support for ITE IT8705F, IT8712F,
@@ -824,6 +827,7 @@ config SENSORS_NTC_THERMISTOR
 
 config SENSORS_PC87360
        tristate "National Semiconductor PC87360 family"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here you get access to the hardware monitoring
@@ -837,6 +841,7 @@ config SENSORS_PC87360
 
 config SENSORS_PC87427
        tristate "National Semiconductor PC87427"
+       depends on !PPC
        help
          If you say yes here you get access to the hardware monitoring
          functions of the National Semiconductor PC87427 Super-I/O chip.
@@ -928,7 +933,7 @@ config SENSORS_SMM665
 
 config SENSORS_DME1737
        tristate "SMSC DME1737, SCH311x and compatibles"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C && EXPERIMENTAL && !PPC
        select HWMON_VID
        help
          If you say yes here you get support for the hardware monitoring
@@ -970,6 +975,7 @@ config SENSORS_EMC6W201
 
 config SENSORS_SMSC47M1
        tristate "SMSC LPC47M10x and compatibles"
+       depends on !PPC
        help
          If you say yes here you get support for the integrated fan
          monitoring and control capabilities of the SMSC LPC47B27x,
@@ -1003,7 +1009,7 @@ config SENSORS_SMSC47M192
 
 config SENSORS_SMSC47B397
        tristate "SMSC LPC47B397-NC"
-       depends on EXPERIMENTAL
+       depends on EXPERIMENTAL && !PPC
        help
          If you say yes here you get support for the SMSC LPC47B397-NC
          sensor chip.
@@ -1017,6 +1023,7 @@ config SENSORS_SCH56XX_COMMON
 
 config SENSORS_SCH5627
        tristate "SMSC SCH5627"
+       depends on !PPC
        select SENSORS_SCH56XX_COMMON
        help
          If you say yes here you get support for the hardware monitoring
@@ -1027,6 +1034,7 @@ config SENSORS_SCH5627
 
 config SENSORS_SCH5636
        tristate "SMSC SCH5636"
+       depends on !PPC
        select SENSORS_SCH56XX_COMMON
        help
          SMSC SCH5636 Super I/O chips include an embedded microcontroller for
@@ -1150,6 +1158,7 @@ config SENSORS_VIA686A
 
 config SENSORS_VT1211
        tristate "VIA VT1211"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here then you get support for hardware monitoring
@@ -1262,6 +1271,7 @@ config SENSORS_W83L786NG
 
 config SENSORS_W83627HF
        tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here you get support for the Winbond W836X7 series
@@ -1272,7 +1282,8 @@ config SENSORS_W83627HF
          will be called w83627hf.
 
 config SENSORS_W83627EHF
-       tristate "Winbond W83627EHF/EHG/DHG, W83667HG, NCT6775F, NCT6776F"
+       tristate "Winbond W83627EHF/EHG/DHG/UHG, W83667HG, NCT6775F, NCT6776F"
+       depends on !PPC
        select HWMON_VID
        help
          If you say yes here you get support for the hardware
@@ -1281,7 +1292,8 @@ config SENSORS_W83627EHF
          This driver also supports the W83627EHG, which is the lead-free
          version of the W83627EHF, and the W83627DHG, which is a similar
          chip suited for specific Intel processors that use PECI such as
-         the Core 2 Duo.
+         the Core 2 Duo. And also the W83627UHG, which is a stripped down
+         version of the W83627DHG (as far as hardware monitoring goes.)
 
          This driver also supports Nuvoton W83667HG, W83667HG-B, NCT6775F
          (also known as W83667HG-I), and NCT6776F.
index d46c0c7..df29a7f 100644 (file)
@@ -58,10 +58,9 @@ static inline int ad7414_temp_from_reg(s16 reg)
 
 static inline int ad7414_read(struct i2c_client *client, u8 reg)
 {
-       if (reg == AD7414_REG_TEMP) {
-               int value = i2c_smbus_read_word_data(client, reg);
-               return (value < 0) ? value : swab16(value);
-       } else
+       if (reg == AD7414_REG_TEMP)
+               return i2c_smbus_read_word_swapped(client, reg);
+       else
                return i2c_smbus_read_byte_data(client, reg);
 }
 
index ffc781f..8cb718c 100644 (file)
@@ -76,20 +76,6 @@ static struct i2c_driver ad7418_driver = {
        .id_table       = ad7418_id,
 };
 
-/* All registers are word-sized, except for the configuration registers.
- * AD7418 uses a high-byte first convention. Do NOT use those functions to
- * access the configuration registers CONF and CONF2, as they are byte-sized.
- */
-static inline int ad7418_read(struct i2c_client *client, u8 reg)
-{
-       return swab16(i2c_smbus_read_word_data(client, reg));
-}
-
-static inline int ad7418_write(struct i2c_client *client, u8 reg, u16 value)
-{
-       return i2c_smbus_write_word_data(client, reg, swab16(value));
-}
-
 static void ad7418_init_client(struct i2c_client *client)
 {
        struct ad7418_data *data = i2c_get_clientdata(client);
@@ -128,7 +114,9 @@ static struct ad7418_data *ad7418_update_device(struct device *dev)
                udelay(30);
 
                for (i = 0; i < 3; i++) {
-                       data->temp[i] = ad7418_read(client, AD7418_REG_TEMP[i]);
+                       data->temp[i] =
+                               i2c_smbus_read_word_swapped(client,
+                                               AD7418_REG_TEMP[i]);
                }
 
                for (i = 0, ch = 4; i < data->adc_max; i++, ch--) {
@@ -138,11 +126,12 @@ static struct ad7418_data *ad7418_update_device(struct device *dev)
 
                        udelay(15);
                        data->in[data->adc_max - 1 - i] =
-                               ad7418_read(client, AD7418_REG_ADC);
+                               i2c_smbus_read_word_swapped(client,
+                                               AD7418_REG_ADC);
                }
 
                /* restore old configuration value */
-               ad7418_write(client, AD7418_REG_CONF, cfg);
+               i2c_smbus_write_word_swapped(client, AD7418_REG_CONF, cfg);
 
                data->last_updated = jiffies;
                data->valid = 1;
@@ -182,7 +171,9 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
 
        mutex_lock(&data->lock);
        data->temp[attr->index] = LM75_TEMP_TO_REG(temp);
-       ad7418_write(client, AD7418_REG_TEMP[attr->index], data->temp[attr->index]);
+       i2c_smbus_write_word_swapped(client,
+                                    AD7418_REG_TEMP[attr->index],
+                                    data->temp[attr->index]);
        mutex_unlock(&data->lock);
        return count;
 }
index e9beeda..eedca3c 100644 (file)
@@ -59,19 +59,6 @@ struct ads1015_data {
        struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
 };
 
-static s32 ads1015_read_reg(struct i2c_client *client, unsigned int reg)
-{
-       s32 data = i2c_smbus_read_word_data(client, reg);
-
-       return (data < 0) ? data : swab16(data);
-}
-
-static s32 ads1015_write_reg(struct i2c_client *client, unsigned int reg,
-                            u16 val)
-{
-       return i2c_smbus_write_word_data(client, reg, swab16(val));
-}
-
 static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
                              int *value)
 {
@@ -87,7 +74,7 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
        mutex_lock(&data->update_lock);
 
        /* get channel parameters */
-       res = ads1015_read_reg(client, ADS1015_CONFIG);
+       res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG);
        if (res < 0)
                goto err_unlock;
        config = res;
@@ -101,13 +88,13 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
        config |= (pga & 0x0007) << 9;
        config |= (data_rate & 0x0007) << 5;
 
-       res = ads1015_write_reg(client, ADS1015_CONFIG, config);
+       res = i2c_smbus_write_word_swapped(client, ADS1015_CONFIG, config);
        if (res < 0)
                goto err_unlock;
 
        /* wait until conversion finished */
        msleep(conversion_time_ms);
-       res = ads1015_read_reg(client, ADS1015_CONFIG);
+       res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG);
        if (res < 0)
                goto err_unlock;
        config = res;
@@ -117,7 +104,7 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
                goto err_unlock;
        }
 
-       res = ads1015_read_reg(client, ADS1015_CONVERSION);
+       res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION);
        if (res < 0)
                goto err_unlock;
        conversion = res;
index c42c5a6..cfcc3b6 100644 (file)
@@ -74,13 +74,6 @@ static int ads7828_detect(struct i2c_client *client,
 static int ads7828_probe(struct i2c_client *client,
                         const struct i2c_device_id *id);
 
-/* The ADS7828 returns the 12-bit sample in two bytes,
-       these are read as a word then byte-swapped */
-static u16 ads7828_read_value(struct i2c_client *client, u8 reg)
-{
-       return swab16(i2c_smbus_read_word_data(client, reg));
-}
-
 static inline u8 channel_cmd_byte(int ch)
 {
        /* cmd byte C2,C1,C0 - see datasheet */
@@ -104,7 +97,8 @@ static struct ads7828_data *ads7828_update_device(struct device *dev)
 
                for (ch = 0; ch < ADS7828_NCH; ch++) {
                        u8 cmd = channel_cmd_byte(ch);
-                       data->adc_input[ch] = ads7828_read_value(client, cmd);
+                       data->adc_input[ch] =
+                               i2c_smbus_read_word_swapped(client, cmd);
                }
                data->last_updated = jiffies;
                data->valid = 1;
@@ -203,7 +197,7 @@ static int ads7828_detect(struct i2c_client *client,
        for (ch = 0; ch < ADS7828_NCH; ch++) {
                u16 in_data;
                u8 cmd = channel_cmd_byte(ch);
-               in_data = ads7828_read_value(client, cmd);
+               in_data = i2c_smbus_read_word_swapped(client, cmd);
                if (in_data & 0xF000) {
                        pr_debug("%s : Doesn't look like an ads7828 device\n",
                                 __func__);
index c02a052..d7bd1f3 100644 (file)
@@ -829,17 +829,17 @@ static int asb100_read_value(struct i2c_client *client, u16 reg)
                /* convert from ISA to LM75 I2C addresses */
                switch (reg & 0xff) {
                case 0x50: /* TEMP */
-                       res = swab16(i2c_smbus_read_word_data(cl, 0));
+                       res = i2c_smbus_read_word_swapped(cl, 0);
                        break;
                case 0x52: /* CONFIG */
                        res = i2c_smbus_read_byte_data(cl, 1);
                        break;
                case 0x53: /* HYST */
-                       res = swab16(i2c_smbus_read_word_data(cl, 2));
+                       res = i2c_smbus_read_word_swapped(cl, 2);
                        break;
                case 0x55: /* MAX */
                default:
-                       res = swab16(i2c_smbus_read_word_data(cl, 3));
+                       res = i2c_smbus_read_word_swapped(cl, 3);
                        break;
                }
        }
@@ -877,10 +877,10 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value)
                        i2c_smbus_write_byte_data(cl, 1, value & 0xff);
                        break;
                case 0x53: /* HYST */
-                       i2c_smbus_write_word_data(cl, 2, swab16(value));
+                       i2c_smbus_write_word_swapped(cl, 2, value);
                        break;
                case 0x55: /* MAX */
-                       i2c_smbus_write_word_data(cl, 3, swab16(value));
+                       i2c_smbus_write_word_swapped(cl, 3, value);
                        break;
                }
        }
index e113634..ef1ac99 100644 (file)
@@ -80,24 +80,6 @@ struct ds1621_data {
        u8 conf;                        /* Register encoding, combined */
 };
 
-/* Temperature registers are word-sized.
-   DS1621 uses a high-byte first convention, which is exactly opposite to
-   the SMBus standard. */
-static int ds1621_read_temp(struct i2c_client *client, u8 reg)
-{
-       int ret;
-
-       ret = i2c_smbus_read_word_data(client, reg);
-       if (ret < 0)
-               return ret;
-       return swab16(ret);
-}
-
-static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value)
-{
-       return i2c_smbus_write_word_data(client, reg, swab16(value));
-}
-
 static void ds1621_init_client(struct i2c_client *client)
 {
        u8 conf, new_conf;
@@ -136,7 +118,7 @@ static struct ds1621_data *ds1621_update_client(struct device *dev)
                data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
 
                for (i = 0; i < ARRAY_SIZE(data->temp); i++)
-                       data->temp[i] = ds1621_read_temp(client,
+                       data->temp[i] = i2c_smbus_read_word_swapped(client,
                                                         DS1621_REG_TEMP[i]);
 
                /* reset alarms if necessary */
@@ -177,8 +159,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
 
        mutex_lock(&data->update_lock);
        data->temp[attr->index] = val;
-       ds1621_write_temp(client, DS1621_REG_TEMP[attr->index],
-                         data->temp[attr->index]);
+       i2c_smbus_write_word_swapped(client, DS1621_REG_TEMP[attr->index],
+                                    data->temp[attr->index]);
        mutex_unlock(&data->update_lock);
        return count;
 }
index 4f7c3fc..225ae4f 100644 (file)
@@ -75,33 +75,13 @@ struct ds620_data {
        s16 temp[3];            /* Register values, word */
 };
 
-/*
- *  Temperature registers are word-sized.
- *  DS620 uses a high-byte first convention, which is exactly opposite to
- *  the SMBus standard.
- */
-static int ds620_read_temp(struct i2c_client *client, u8 reg)
-{
-       int ret;
-
-       ret = i2c_smbus_read_word_data(client, reg);
-       if (ret < 0)
-               return ret;
-       return swab16(ret);
-}
-
-static int ds620_write_temp(struct i2c_client *client, u8 reg, u16 value)
-{
-       return i2c_smbus_write_word_data(client, reg, swab16(value));
-}
-
 static void ds620_init_client(struct i2c_client *client)
 {
        struct ds620_platform_data *ds620_info = client->dev.platform_data;
        u16 conf, new_conf;
 
        new_conf = conf =
-           swab16(i2c_smbus_read_word_data(client, DS620_REG_CONF));
+           i2c_smbus_read_word_swapped(client, DS620_REG_CONF);
 
        /* switch to continuous conversion mode */
        new_conf &= ~DS620_REG_CONFIG_1SHOT;
@@ -118,8 +98,7 @@ static void ds620_init_client(struct i2c_client *client)
        new_conf |= DS620_REG_CONFIG_R1 | DS620_REG_CONFIG_R0;
 
        if (conf != new_conf)
-               i2c_smbus_write_word_data(client, DS620_REG_CONF,
-                                         swab16(new_conf));
+               i2c_smbus_write_word_swapped(client, DS620_REG_CONF, new_conf);
 
        /* start conversion */
        i2c_smbus_write_byte(client, DS620_COM_START);
@@ -141,8 +120,8 @@ static struct ds620_data *ds620_update_client(struct device *dev)
                dev_dbg(&client->dev, "Starting ds620 update\n");
 
                for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
-                       res = ds620_read_temp(client,
-                                             DS620_REG_TEMP[i]);
+                       res = i2c_smbus_read_word_swapped(client,
+                                                         DS620_REG_TEMP[i]);
                        if (res < 0) {
                                ret = ERR_PTR(res);
                                goto abort;
@@ -191,8 +170,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
 
        mutex_lock(&data->update_lock);
        data->temp[attr->index] = val;
-       ds620_write_temp(client, DS620_REG_TEMP[attr->index],
-                        data->temp[attr->index]);
+       i2c_smbus_write_word_swapped(client, DS620_REG_TEMP[attr->index],
+                                    data->temp[attr->index]);
        mutex_unlock(&data->update_lock);
        return count;
 }
@@ -210,16 +189,15 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
                return PTR_ERR(data);
 
        /* reset alarms if necessary */
-       res = i2c_smbus_read_word_data(client, DS620_REG_CONF);
+       res = i2c_smbus_read_word_swapped(client, DS620_REG_CONF);
        if (res < 0)
                return res;
 
-       conf = swab16(res);
-       new_conf = conf;
+       new_conf = conf = res;
        new_conf &= ~attr->index;
        if (conf != new_conf) {
-               res = i2c_smbus_write_word_data(client, DS620_REG_CONF,
-                                               swab16(new_conf));
+               res = i2c_smbus_write_word_swapped(client, DS620_REG_CONF,
+                                                  new_conf);
                if (res < 0)
                        return res;
        }
index e7ae574..a13e2da 100644 (file)
@@ -591,7 +591,7 @@ static int gl518_remove(struct i2c_client *client)
 static int gl518_read_value(struct i2c_client *client, u8 reg)
 {
        if ((reg >= 0x07) && (reg <= 0x0c))
-               return swab16(i2c_smbus_read_word_data(client, reg));
+               return i2c_smbus_read_word_swapped(client, reg);
        else
                return i2c_smbus_read_byte_data(client, reg);
 }
@@ -599,7 +599,7 @@ static int gl518_read_value(struct i2c_client *client, u8 reg)
 static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
 {
        if ((reg >= 0x07) && (reg <= 0x0c))
-               return i2c_smbus_write_word_data(client, reg, swab16(value));
+               return i2c_smbus_write_word_swapped(client, reg, value);
        else
                return i2c_smbus_write_byte_data(client, reg, value);
 }
index 131ea86..cd6085b 100644 (file)
@@ -821,7 +821,7 @@ static int gl520_remove(struct i2c_client *client)
 static int gl520_read_value(struct i2c_client *client, u8 reg)
 {
        if ((reg >= 0x07) && (reg <= 0x0c))
-               return swab16(i2c_smbus_read_word_data(client, reg));
+               return i2c_smbus_read_word_swapped(client, reg);
        else
                return i2c_smbus_read_byte_data(client, reg);
 }
@@ -829,7 +829,7 @@ static int gl520_read_value(struct i2c_client *client, u8 reg)
 static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value)
 {
        if ((reg >= 0x07) && (reg <= 0x0c))
-               return i2c_smbus_write_word_data(client, reg, swab16(value));
+               return i2c_smbus_write_word_swapped(client, reg, value);
        else
                return i2c_smbus_write_byte_data(client, reg, value);
 }
index 783d0c1..6a967d7 100644 (file)
@@ -147,8 +147,9 @@ struct aem_data {
        int                     id;
        struct aem_ipmi_data    ipmi;
 
-       /* Function to update sensors */
+       /* Function and buffer to update sensors */
        void (*update)(struct aem_data *data);
+       struct aem_read_sensor_resp *rs_resp;
 
        /*
         * AEM 1.x sensors:
@@ -245,8 +246,6 @@ static void aem_bmc_gone(int iface);
 static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
 
 static void aem_remove_sensors(struct aem_data *data);
-static int aem_init_aem1(struct aem_ipmi_data *probe);
-static int aem_init_aem2(struct aem_ipmi_data *probe);
 static int aem1_find_sensors(struct aem_data *data);
 static int aem2_find_sensors(struct aem_data *data);
 static void update_aem1_sensors(struct aem_data *data);
@@ -357,13 +356,14 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
 
 /* Sensor support functions */
 
-/* Read a sensor value */
+/* Read a sensor value; must be called with data->lock held */
 static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
                           void *buf, size_t size)
 {
        int rs_size, res;
        struct aem_read_sensor_req rs_req;
-       struct aem_read_sensor_resp *rs_resp;
+       /* Use preallocated rx buffer */
+       struct aem_read_sensor_resp *rs_resp = data->rs_resp;
        struct aem_ipmi_data *ipmi = &data->ipmi;
 
        /* AEM registers are 1, 2, 4 or 8 bytes */
@@ -389,10 +389,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
        ipmi->tx_message.data_len = sizeof(rs_req);
 
        rs_size = sizeof(*rs_resp) + size;
-       rs_resp = kzalloc(rs_size, GFP_KERNEL);
-       if (!rs_resp)
-               return -ENOMEM;
-
        ipmi->rx_msg_data = rs_resp;
        ipmi->rx_msg_len = rs_size;
 
@@ -435,7 +431,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
        res = 0;
 
 out:
-       kfree(rs_resp);
        return res;
 }
 
@@ -493,6 +488,7 @@ static void aem_delete(struct aem_data *data)
 {
        list_del(&data->list);
        aem_remove_sensors(data);
+       kfree(data->rs_resp);
        hwmon_device_unregister(data->hwmon_dev);
        ipmi_destroy_user(data->ipmi.user);
        platform_set_drvdata(data->pdev, NULL);
@@ -570,24 +566,31 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
        platform_set_drvdata(data->pdev, data);
 
        /* Set up IPMI interface */
-       if (aem_init_ipmi_data(&data->ipmi, probe->interface,
-                              probe->bmc_device))
+       res = aem_init_ipmi_data(&data->ipmi, probe->interface,
+                                probe->bmc_device);
+       if (res)
                goto ipmi_err;
 
        /* Register with hwmon */
        data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
-
        if (IS_ERR(data->hwmon_dev)) {
                dev_err(&data->pdev->dev, "Unable to register hwmon "
                        "device for IPMI interface %d\n",
                        probe->interface);
+               res = PTR_ERR(data->hwmon_dev);
                goto hwmon_reg_err;
        }
 
        data->update = update_aem1_sensors;
+       data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
+       if (!data->rs_resp) {
+               res = -ENOMEM;
+               goto alloc_resp_err;
+       }
 
        /* Find sensors */
-       if (aem1_find_sensors(data))
+       res = aem1_find_sensors(data);
+       if (res)
                goto sensor_err;
 
        /* Add to our list of AEM devices */
@@ -599,6 +602,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
        return 0;
 
 sensor_err:
+       kfree(data->rs_resp);
+alloc_resp_err:
        hwmon_device_unregister(data->hwmon_dev);
 hwmon_reg_err:
        ipmi_destroy_user(data->ipmi.user);
@@ -614,7 +619,7 @@ id_err:
 }
 
 /* Find and initialize all AEM1 instances */
-static int aem_init_aem1(struct aem_ipmi_data *probe)
+static void aem_init_aem1(struct aem_ipmi_data *probe)
 {
        int num, i, err;
 
@@ -625,11 +630,8 @@ static int aem_init_aem1(struct aem_ipmi_data *probe)
                        dev_err(probe->bmc_device,
                                "Error %d initializing AEM1 0x%X\n",
                                err, i);
-                       return err;
                }
        }
-
-       return 0;
 }
 
 /* Probe functions for AEM2 devices */
@@ -704,24 +706,31 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
        platform_set_drvdata(data->pdev, data);
 
        /* Set up IPMI interface */
-       if (aem_init_ipmi_data(&data->ipmi, probe->interface,
-                              probe->bmc_device))
+       res = aem_init_ipmi_data(&data->ipmi, probe->interface,
+                                probe->bmc_device);
+       if (res)
                goto ipmi_err;
 
        /* Register with hwmon */
        data->hwmon_dev = hwmon_device_register(&data->pdev->dev);
-
        if (IS_ERR(data->hwmon_dev)) {
                dev_err(&data->pdev->dev, "Unable to register hwmon "
                        "device for IPMI interface %d\n",
                        probe->interface);
+               res = PTR_ERR(data->hwmon_dev);
                goto hwmon_reg_err;
        }
 
        data->update = update_aem2_sensors;
+       data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
+       if (!data->rs_resp) {
+               res = -ENOMEM;
+               goto alloc_resp_err;
+       }
 
        /* Find sensors */
-       if (aem2_find_sensors(data))
+       res = aem2_find_sensors(data);
+       if (res)
                goto sensor_err;
 
        /* Add to our list of AEM devices */
@@ -733,6 +742,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
        return 0;
 
 sensor_err:
+       kfree(data->rs_resp);
+alloc_resp_err:
        hwmon_device_unregister(data->hwmon_dev);
 hwmon_reg_err:
        ipmi_destroy_user(data->ipmi.user);
@@ -748,7 +759,7 @@ id_err:
 }
 
 /* Find and initialize all AEM2 instances */
-static int aem_init_aem2(struct aem_ipmi_data *probe)
+static void aem_init_aem2(struct aem_ipmi_data *probe)
 {
        struct aem_find_instance_resp fi_resp;
        int err;
@@ -767,12 +778,9 @@ static int aem_init_aem2(struct aem_ipmi_data *probe)
                        dev_err(probe->bmc_device,
                                "Error %d initializing AEM2 0x%X\n",
                                err, fi_resp.module_handle);
-                       return err;
                }
                i++;
        }
-
-       return 0;
 }
 
 /* Probe a BMC for AEM firmware instances */
index 02cebb7..2d3d728 100644 (file)
@@ -154,8 +154,6 @@ static int jc42_probe(struct i2c_client *client,
                      const struct i2c_device_id *id);
 static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info);
 static int jc42_remove(struct i2c_client *client);
-static int jc42_read_value(struct i2c_client *client, u8 reg);
-static int jc42_write_value(struct i2c_client *client, u8 reg, u16 value);
 
 static struct jc42_data *jc42_update_device(struct device *dev);
 
@@ -187,7 +185,7 @@ static int jc42_suspend(struct device *dev)
        struct jc42_data *data = i2c_get_clientdata(client);
 
        data->config |= JC42_CFG_SHUTDOWN;
-       jc42_write_value(client, JC42_REG_CONFIG, data->config);
+       i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config);
        return 0;
 }
 
@@ -197,7 +195,7 @@ static int jc42_resume(struct device *dev)
        struct jc42_data *data = i2c_get_clientdata(client);
 
        data->config &= ~JC42_CFG_SHUTDOWN;
-       jc42_write_value(client, JC42_REG_CONFIG, data->config);
+       i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config);
        return 0;
 }
 
@@ -315,7 +313,7 @@ static ssize_t set_##value(struct device *dev,                              \
                return -EINVAL;                                         \
        mutex_lock(&data->update_lock);                                 \
        data->value = jc42_temp_to_reg(val, data->extended);            \
-       err = jc42_write_value(client, reg, data->value);               \
+       err = i2c_smbus_write_word_swapped(client, reg, data->value);   \
        if (err < 0)                                                    \
                ret = err;                                              \
        mutex_unlock(&data->update_lock);                               \
@@ -357,7 +355,8 @@ static ssize_t set_temp_crit_hyst(struct device *dev,
        data->config = (data->config
                        & ~(JC42_CFG_HYST_MASK << JC42_CFG_HYST_SHIFT))
          | (hyst << JC42_CFG_HYST_SHIFT);
-       err = jc42_write_value(client, JC42_REG_CONFIG, data->config);
+       err = i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG,
+                                          data->config);
        if (err < 0)
                ret = err;
        mutex_unlock(&data->update_lock);
@@ -452,10 +451,10 @@ static int jc42_detect(struct i2c_client *new_client,
                                     I2C_FUNC_SMBUS_WORD_DATA))
                return -ENODEV;
 
-       cap = jc42_read_value(new_client, JC42_REG_CAP);
-       config = jc42_read_value(new_client, JC42_REG_CONFIG);
-       manid = jc42_read_value(new_client, JC42_REG_MANID);
-       devid = jc42_read_value(new_client, JC42_REG_DEVICEID);
+       cap = i2c_smbus_read_word_swapped(new_client, JC42_REG_CAP);
+       config = i2c_smbus_read_word_swapped(new_client, JC42_REG_CONFIG);
+       manid = i2c_smbus_read_word_swapped(new_client, JC42_REG_MANID);
+       devid = i2c_smbus_read_word_swapped(new_client, JC42_REG_DEVICEID);
 
        if (cap < 0 || config < 0 || manid < 0 || devid < 0)
                return -ENODEV;
@@ -489,14 +488,14 @@ static int jc42_probe(struct i2c_client *new_client,
        i2c_set_clientdata(new_client, data);
        mutex_init(&data->update_lock);
 
-       cap = jc42_read_value(new_client, JC42_REG_CAP);
+       cap = i2c_smbus_read_word_swapped(new_client, JC42_REG_CAP);
        if (cap < 0) {
                err = -EINVAL;
                goto exit_free;
        }
        data->extended = !!(cap & JC42_CAP_RANGE);
 
-       config = jc42_read_value(new_client, JC42_REG_CONFIG);
+       config = i2c_smbus_read_word_swapped(new_client, JC42_REG_CONFIG);
        if (config < 0) {
                err = -EINVAL;
                goto exit_free;
@@ -504,7 +503,8 @@ static int jc42_probe(struct i2c_client *new_client,
        data->orig_config = config;
        if (config & JC42_CFG_SHUTDOWN) {
                config &= ~JC42_CFG_SHUTDOWN;
-               jc42_write_value(new_client, JC42_REG_CONFIG, config);
+               i2c_smbus_write_word_swapped(new_client, JC42_REG_CONFIG,
+                                            config);
        }
        data->config = config;
 
@@ -535,25 +535,12 @@ static int jc42_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &jc42_group);
        if (data->config != data->orig_config)
-               jc42_write_value(client, JC42_REG_CONFIG, data->orig_config);
+               i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG,
+                                            data->orig_config);
        kfree(data);
        return 0;
 }
 
-/* All registers are word-sized. */
-static int jc42_read_value(struct i2c_client *client, u8 reg)
-{
-       int ret = i2c_smbus_read_word_data(client, reg);
-       if (ret < 0)
-               return ret;
-       return swab16(ret);
-}
-
-static int jc42_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-       return i2c_smbus_write_word_data(client, reg, swab16(value));
-}
-
 static struct jc42_data *jc42_update_device(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
@@ -564,28 +551,29 @@ static struct jc42_data *jc42_update_device(struct device *dev)
        mutex_lock(&data->update_lock);
 
        if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
-               val = jc42_read_value(client, JC42_REG_TEMP);
+               val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP);
                if (val < 0) {
                        ret = ERR_PTR(val);
                        goto abort;
                }
                data->temp_input = val;
 
-               val = jc42_read_value(client, JC42_REG_TEMP_CRITICAL);
+               val = i2c_smbus_read_word_swapped(client,
+                                                 JC42_REG_TEMP_CRITICAL);
                if (val < 0) {
                        ret = ERR_PTR(val);
                        goto abort;
                }
                data->temp_crit = val;
 
-               val = jc42_read_value(client, JC42_REG_TEMP_LOWER);
+               val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_LOWER);
                if (val < 0) {
                        ret = ERR_PTR(val);
                        goto abort;
                }
                data->temp_min = val;
 
-               val = jc42_read_value(client, JC42_REG_TEMP_UPPER);
+               val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_UPPER);
                if (val < 0) {
                        ret = ERR_PTR(val);
                        goto abort;
index 29b9030..9e64d96 100644 (file)
@@ -34,7 +34,7 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c,
 #define LM73_REG_CTRL          0x04
 #define LM73_REG_ID            0x07
 
-#define LM73_ID                        0x9001 /* or 0x190 after a swab16() */
+#define LM73_ID                        0x9001  /* 0x0190, byte-swapped */
 #define DRVNAME                        "lm73"
 #define LM73_TEMP_MIN          (-40)
 #define LM73_TEMP_MAX          150
@@ -57,7 +57,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
        /* Write value */
        value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4),
                (LM73_TEMP_MAX*4)) << 5;
-       i2c_smbus_write_word_data(client, attr->index, swab16(value));
+       i2c_smbus_write_word_swapped(client, attr->index, value);
        return count;
 }
 
@@ -68,8 +68,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da,
        struct i2c_client *client = to_i2c_client(dev);
        /* use integer division instead of equivalent right shift to
           guarantee arithmetic shift and preserve the sign */
-       int temp = ((s16) (swab16(i2c_smbus_read_word_data(client,
-               attr->index)))*250) / 32;
+       int temp = ((s16) (i2c_smbus_read_word_swapped(client,
+                   attr->index))*250) / 32;
        return sprintf(buf, "%d\n", temp);
 }
 
@@ -150,17 +150,31 @@ static int lm73_detect(struct i2c_client *new_client,
                        struct i2c_board_info *info)
 {
        struct i2c_adapter *adapter = new_client->adapter;
-       u16 id;
-       u8 ctrl;
+       int id, ctrl, conf;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
                                        I2C_FUNC_SMBUS_WORD_DATA))
                return -ENODEV;
 
+       /*
+        * Do as much detection as possible with byte reads first, as word
+        * reads can confuse other devices.
+        */
+       ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL);
+       if (ctrl < 0 || (ctrl & 0x10))
+               return -ENODEV;
+
+       conf = i2c_smbus_read_byte_data(new_client, LM73_REG_CONF);
+       if (conf < 0 || (conf & 0x0c))
+               return -ENODEV;
+
+       id = i2c_smbus_read_byte_data(new_client, LM73_REG_ID);
+       if (id < 0 || id != (LM73_ID & 0xff))
+               return -ENODEV;
+
        /* Check device ID */
        id = i2c_smbus_read_word_data(new_client, LM73_REG_ID);
-       ctrl = i2c_smbus_read_byte_data(new_client, LM73_REG_CTRL);
-       if ((id != LM73_ID) || (ctrl & 0x10))
+       if (id < 0 || id != LM73_ID)
                return -ENODEV;
 
        strlcpy(info->type, "lm73", I2C_NAME_SIZE);
index 90126a2..1888dd0 100644 (file)
@@ -384,13 +384,10 @@ static struct i2c_driver lm75_driver = {
  */
 static int lm75_read_value(struct i2c_client *client, u8 reg)
 {
-       int value;
-
        if (reg == LM75_REG_CONF)
                return i2c_smbus_read_byte_data(client, reg);
-
-       value = i2c_smbus_read_word_data(client, reg);
-       return (value < 0) ? value : swab16(value);
+       else
+               return i2c_smbus_read_word_swapped(client, reg);
 }
 
 static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
@@ -398,7 +395,7 @@ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
        if (reg == LM75_REG_CONF)
                return i2c_smbus_write_byte_data(client, reg, value);
        else
-               return i2c_smbus_write_word_data(client, reg, swab16(value));
+               return i2c_smbus_write_word_swapped(client, reg, value);
 }
 
 static struct lm75_data *lm75_update_device(struct device *dev)
index b28a297..8dfc678 100644 (file)
@@ -365,7 +365,7 @@ static u16 lm77_read_value(struct i2c_client *client, u8 reg)
        if (reg == LM77_REG_CONF)
                return i2c_smbus_read_byte_data(client, reg);
        else
-               return swab16(i2c_smbus_read_word_data(client, reg));
+               return i2c_smbus_read_word_swapped(client, reg);
 }
 
 static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value)
@@ -373,7 +373,7 @@ static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value)
        if (reg == LM77_REG_CONF)
                return i2c_smbus_write_byte_data(client, reg, value);
        else
-               return i2c_smbus_write_word_data(client, reg, swab16(value));
+               return i2c_smbus_write_word_swapped(client, reg, value);
 }
 
 static void lm77_init_client(struct i2c_client *client)
index 90ddb87..615bc4f 100644 (file)
@@ -1105,41 +1105,37 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec);
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm90_detect(struct i2c_client *new_client,
+static int lm90_detect(struct i2c_client *client,
                       struct i2c_board_info *info)
 {
-       struct i2c_adapter *adapter = new_client->adapter;
-       int address = new_client->addr;
+       struct i2c_adapter *adapter = client->adapter;
+       int address = client->addr;
        const char *name = NULL;
-       int man_id, chip_id, reg_config1, reg_config2, reg_convrate;
+       int man_id, chip_id, config1, config2, convrate;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -ENODEV;
 
        /* detection and identification */
-       if ((man_id = i2c_smbus_read_byte_data(new_client,
-                                               LM90_REG_R_MAN_ID)) < 0
-        || (chip_id = i2c_smbus_read_byte_data(new_client,
-                                               LM90_REG_R_CHIP_ID)) < 0
-        || (reg_config1 = i2c_smbus_read_byte_data(new_client,
-                                               LM90_REG_R_CONFIG1)) < 0
-        || (reg_convrate = i2c_smbus_read_byte_data(new_client,
-                                               LM90_REG_R_CONVRATE)) < 0)
+       man_id = i2c_smbus_read_byte_data(client, LM90_REG_R_MAN_ID);
+       chip_id = i2c_smbus_read_byte_data(client, LM90_REG_R_CHIP_ID);
+       config1 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1);
+       convrate = i2c_smbus_read_byte_data(client, LM90_REG_R_CONVRATE);
+       if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0)
                return -ENODEV;
 
        if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) {
-               reg_config2 = i2c_smbus_read_byte_data(new_client,
-                                               LM90_REG_R_CONFIG2);
-               if (reg_config2 < 0)
+               config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2);
+               if (config2 < 0)
                        return -ENODEV;
        } else
-               reg_config2 = 0;        /* Make compiler happy */
+               config2 = 0;            /* Make compiler happy */
 
        if ((address == 0x4C || address == 0x4D)
         && man_id == 0x01) { /* National Semiconductor */
-               if ((reg_config1 & 0x2A) == 0x00
-                && (reg_config2 & 0xF8) == 0x00
-                && reg_convrate <= 0x09) {
+               if ((config1 & 0x2A) == 0x00
+                && (config2 & 0xF8) == 0x00
+                && convrate <= 0x09) {
                        if (address == 0x4C
                         && (chip_id & 0xF0) == 0x20) { /* LM90 */
                                name = "lm90";
@@ -1163,8 +1159,8 @@ static int lm90_detect(struct i2c_client *new_client,
        if ((address == 0x4C || address == 0x4D)
         && man_id == 0x41) { /* Analog Devices */
                if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
-                && (reg_config1 & 0x3F) == 0x00
-                && reg_convrate <= 0x0A) {
+                && (config1 & 0x3F) == 0x00
+                && convrate <= 0x0A) {
                        name = "adm1032";
                        /* The ADM1032 supports PEC, but only if combined
                           transactions are not used. */
@@ -1173,18 +1169,18 @@ static int lm90_detect(struct i2c_client *new_client,
                                info->flags |= I2C_CLIENT_PEC;
                } else
                if (chip_id == 0x51 /* ADT7461 */
-                && (reg_config1 & 0x1B) == 0x00
-                && reg_convrate <= 0x0A) {
+                && (config1 & 0x1B) == 0x00
+                && convrate <= 0x0A) {
                        name = "adt7461";
                } else
                if (chip_id == 0x57 /* ADT7461A, NCT1008 */
-                && (reg_config1 & 0x1B) == 0x00
-                && reg_convrate <= 0x0A) {
+                && (config1 & 0x1B) == 0x00
+                && convrate <= 0x0A) {
                        name = "adt7461a";
                }
        } else
        if (man_id == 0x4D) { /* Maxim */
-               int reg_emerg, reg_emerg2, reg_status2;
+               int emerg, emerg2, status2;
 
                /*
                 * We read MAX6659_REG_R_REMOTE_EMERG twice, and re-read
@@ -1192,13 +1188,15 @@ static int lm90_detect(struct i2c_client *new_client,
                 * exists, both readings will reflect the same value. Otherwise,
                 * the readings will be different.
                 */
-               if ((reg_emerg = i2c_smbus_read_byte_data(new_client,
-                                               MAX6659_REG_R_REMOTE_EMERG)) < 0
-                || i2c_smbus_read_byte_data(new_client, LM90_REG_R_MAN_ID) < 0
-                || (reg_emerg2 = i2c_smbus_read_byte_data(new_client,
-                                               MAX6659_REG_R_REMOTE_EMERG)) < 0
-                || (reg_status2 = i2c_smbus_read_byte_data(new_client,
-                                               MAX6696_REG_R_STATUS2)) < 0)
+               emerg = i2c_smbus_read_byte_data(client,
+                                                MAX6659_REG_R_REMOTE_EMERG);
+               man_id = i2c_smbus_read_byte_data(client,
+                                                 LM90_REG_R_MAN_ID);
+               emerg2 = i2c_smbus_read_byte_data(client,
+                                                 MAX6659_REG_R_REMOTE_EMERG);
+               status2 = i2c_smbus_read_byte_data(client,
+                                                  MAX6696_REG_R_STATUS2);
+               if (emerg < 0 || man_id < 0 || emerg2 < 0 || status2 < 0)
                        return -ENODEV;
 
                /*
@@ -1216,8 +1214,8 @@ static int lm90_detect(struct i2c_client *new_client,
                 */
                if (chip_id == man_id
                 && (address == 0x4C || address == 0x4D || address == 0x4E)
-                && (reg_config1 & 0x1F) == (man_id & 0x0F)
-                && reg_convrate <= 0x09) {
+                && (config1 & 0x1F) == (man_id & 0x0F)
+                && convrate <= 0x09) {
                        if (address == 0x4C)
                                name = "max6657";
                        else
@@ -1235,10 +1233,10 @@ static int lm90_detect(struct i2c_client *new_client,
                 * one of those registers exists.
                 */
                if (chip_id == 0x01
-                && (reg_config1 & 0x10) == 0x00
-                && (reg_status2 & 0x01) == 0x00
-                && reg_emerg == reg_emerg2
-                && reg_convrate <= 0x07) {
+                && (config1 & 0x10) == 0x00
+                && (status2 & 0x01) == 0x00
+                && emerg == emerg2
+                && convrate <= 0x07) {
                        name = "max6696";
                } else
                /*
@@ -1248,8 +1246,8 @@ static int lm90_detect(struct i2c_client *new_client,
                 * second to last bit of config1 (software reset).
                 */
                if (chip_id == 0x01
-                && (reg_config1 & 0x03) == 0x00
-                && reg_convrate <= 0x07) {
+                && (config1 & 0x03) == 0x00
+                && convrate <= 0x07) {
                        name = "max6680";
                } else
                /*
@@ -1258,21 +1256,21 @@ static int lm90_detect(struct i2c_client *new_client,
                 * register are unused and should return zero when read.
                 */
                if (chip_id == 0x59
-                && (reg_config1 & 0x3f) == 0x00
-                && reg_convrate <= 0x07) {
+                && (config1 & 0x3f) == 0x00
+                && convrate <= 0x07) {
                        name = "max6646";
                }
        } else
        if (address == 0x4C
         && man_id == 0x5C) { /* Winbond/Nuvoton */
-               if ((reg_config1 & 0x2A) == 0x00
-                && (reg_config2 & 0xF8) == 0x00) {
+               if ((config1 & 0x2A) == 0x00
+                && (config2 & 0xF8) == 0x00) {
                        if (chip_id == 0x01 /* W83L771W/G */
-                        && reg_convrate <= 0x09) {
+                        && convrate <= 0x09) {
                                name = "w83l771";
                        } else
                        if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */
-                        && reg_convrate <= 0x08) {
+                        && convrate <= 0x08) {
                                name = "w83l771";
                        }
                }
@@ -1280,9 +1278,9 @@ static int lm90_detect(struct i2c_client *new_client,
        if (address >= 0x48 && address <= 0x4F
         && man_id == 0xA1) { /*  NXP Semiconductor/Philips */
                if (chip_id == 0x00
-                && (reg_config1 & 0x2A) == 0x00
-                && (reg_config2 & 0xFE) == 0x00
-                && reg_convrate <= 0x09) {
+                && (config1 & 0x2A) == 0x00
+                && (config2 & 0xFE) == 0x00
+                && convrate <= 0x09) {
                        name = "sa56004";
                }
        }
@@ -1301,19 +1299,18 @@ static int lm90_detect(struct i2c_client *new_client,
 
 static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data)
 {
+       struct device *dev = &client->dev;
+
        if (data->flags & LM90_HAVE_TEMP3)
-               sysfs_remove_group(&client->dev.kobj, &lm90_temp3_group);
+               sysfs_remove_group(&dev->kobj, &lm90_temp3_group);
        if (data->flags & LM90_HAVE_EMERGENCY_ALARM)
-               sysfs_remove_group(&client->dev.kobj,
-                                  &lm90_emergency_alarm_group);
+               sysfs_remove_group(&dev->kobj, &lm90_emergency_alarm_group);
        if (data->flags & LM90_HAVE_EMERGENCY)
-               sysfs_remove_group(&client->dev.kobj,
-                                  &lm90_emergency_group);
+               sysfs_remove_group(&dev->kobj, &lm90_emergency_group);
        if (data->flags & LM90_HAVE_OFFSET)
-               device_remove_file(&client->dev,
-                                  &sensor_dev_attr_temp2_offset.dev_attr);
-       device_remove_file(&client->dev, &dev_attr_pec);
-       sysfs_remove_group(&client->dev.kobj, &lm90_group);
+               device_remove_file(dev, &sensor_dev_attr_temp2_offset.dev_attr);
+       device_remove_file(dev, &dev_attr_pec);
+       sysfs_remove_group(&dev->kobj, &lm90_group);
 }
 
 static void lm90_init_client(struct i2c_client *client)
@@ -1362,10 +1359,11 @@ static void lm90_init_client(struct i2c_client *client)
                i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
 }
 
-static int lm90_probe(struct i2c_client *new_client,
+static int lm90_probe(struct i2c_client *client,
                      const struct i2c_device_id *id)
 {
-       struct i2c_adapter *adapter = to_i2c_adapter(new_client->dev.parent);
+       struct device *dev = &client->dev;
+       struct i2c_adapter *adapter = to_i2c_adapter(dev->parent);
        struct lm90_data *data;
        int err;
 
@@ -1374,14 +1372,14 @@ static int lm90_probe(struct i2c_client *new_client,
                err = -ENOMEM;
                goto exit;
        }
-       i2c_set_clientdata(new_client, data);
+       i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
 
        /* Set the device type */
        data->kind = id->driver_data;
        if (data->kind == adm1032) {
                if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
-                       new_client->flags &= ~I2C_CLIENT_PEC;
+                       client->flags &= ~I2C_CLIENT_PEC;
        }
 
        /* Different devices have different alarm bits triggering the
@@ -1396,43 +1394,41 @@ static int lm90_probe(struct i2c_client *new_client,
        data->max_convrate = lm90_params[data->kind].max_convrate;
 
        /* Initialize the LM90 chip */
-       lm90_init_client(new_client);
+       lm90_init_client(client);
 
        /* Register sysfs hooks */
-       err = sysfs_create_group(&new_client->dev.kobj, &lm90_group);
+       err = sysfs_create_group(&dev->kobj, &lm90_group);
        if (err)
                goto exit_free;
-       if (new_client->flags & I2C_CLIENT_PEC) {
-               err = device_create_file(&new_client->dev, &dev_attr_pec);
+       if (client->flags & I2C_CLIENT_PEC) {
+               err = device_create_file(dev, &dev_attr_pec);
                if (err)
                        goto exit_remove_files;
        }
        if (data->flags & LM90_HAVE_OFFSET) {
-               err = device_create_file(&new_client->dev,
+               err = device_create_file(dev,
                                        &sensor_dev_attr_temp2_offset.dev_attr);
                if (err)
                        goto exit_remove_files;
        }
        if (data->flags & LM90_HAVE_EMERGENCY) {
-               err = sysfs_create_group(&new_client->dev.kobj,
-                                        &lm90_emergency_group);
+               err = sysfs_create_group(&dev->kobj, &lm90_emergency_group);
                if (err)
                        goto exit_remove_files;
        }
        if (data->flags & LM90_HAVE_EMERGENCY_ALARM) {
-               err = sysfs_create_group(&new_client->dev.kobj,
+               err = sysfs_create_group(&dev->kobj,
                                         &lm90_emergency_alarm_group);
                if (err)
                        goto exit_remove_files;
        }
        if (data->flags & LM90_HAVE_TEMP3) {
-               err = sysfs_create_group(&new_client->dev.kobj,
-                                        &lm90_temp3_group);
+               err = sysfs_create_group(&dev->kobj, &lm90_temp3_group);
                if (err)
                        goto exit_remove_files;
        }
 
-       data->hwmon_dev = hwmon_device_register(&new_client->dev);
+       data->hwmon_dev = hwmon_device_register(dev);
        if (IS_ERR(data->hwmon_dev)) {
                err = PTR_ERR(data->hwmon_dev);
                goto exit_remove_files;
@@ -1441,7 +1437,7 @@ static int lm90_probe(struct i2c_client *new_client,
        return 0;
 
 exit_remove_files:
-       lm90_remove_files(new_client, data);
+       lm90_remove_files(client, data);
 exit_free:
        kfree(data);
 exit:
index 7c31e62..8fcbd4d 100644 (file)
@@ -117,16 +117,16 @@ static struct lm92_data *lm92_update_device(struct device *dev)
        if (time_after(jiffies, data->last_updated + HZ)
         || !data->valid) {
                dev_dbg(&client->dev, "Updating lm92 data\n");
-               data->temp1_input = swab16(i2c_smbus_read_word_data(client,
-                                   LM92_REG_TEMP));
-               data->temp1_hyst = swab16(i2c_smbus_read_word_data(client,
-                                   LM92_REG_TEMP_HYST));
-               data->temp1_crit = swab16(i2c_smbus_read_word_data(client,
-                                   LM92_REG_TEMP_CRIT));
-               data->temp1_min = swab16(i2c_smbus_read_word_data(client,
-                                   LM92_REG_TEMP_LOW));
-               data->temp1_max = swab16(i2c_smbus_read_word_data(client,
-                                   LM92_REG_TEMP_HIGH));
+               data->temp1_input = i2c_smbus_read_word_swapped(client,
+                                   LM92_REG_TEMP);
+               data->temp1_hyst = i2c_smbus_read_word_swapped(client,
+                                   LM92_REG_TEMP_HYST);
+               data->temp1_crit = i2c_smbus_read_word_swapped(client,
+                                   LM92_REG_TEMP_CRIT);
+               data->temp1_min = i2c_smbus_read_word_swapped(client,
+                                   LM92_REG_TEMP_LOW);
+               data->temp1_max = i2c_smbus_read_word_swapped(client,
+                                   LM92_REG_TEMP_HIGH);
 
                data->last_updated = jiffies;
                data->valid = 1;
@@ -158,7 +158,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
  \
        mutex_lock(&data->update_lock); \
        data->value = TEMP_TO_REG(val); \
-       i2c_smbus_write_word_data(client, reg, swab16(data->value)); \
+       i2c_smbus_write_word_swapped(client, reg, data->value); \
        mutex_unlock(&data->update_lock); \
        return count; \
 }
@@ -194,8 +194,8 @@ static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute *
 
        mutex_lock(&data->update_lock);
        data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val;
-       i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST,
-                                 swab16(TEMP_TO_REG(data->temp1_hyst)));
+       i2c_smbus_write_word_swapped(client, LM92_REG_TEMP_HYST,
+                                    TEMP_TO_REG(data->temp1_hyst));
        mutex_unlock(&data->update_lock);
        return count;
 }
index dd2d7b9..385886a 100644 (file)
@@ -137,10 +137,10 @@ static int max16065_read_adc(struct i2c_client *client, int reg)
 {
        int rv;
 
-       rv = i2c_smbus_read_word_data(client, reg);
+       rv = i2c_smbus_read_word_swapped(client, reg);
        if (unlikely(rv < 0))
                return rv;
-       return ((rv & 0xff) << 2) | ((rv >> 14) & 0x03);
+       return rv >> 6;
 }
 
 static struct max16065_data *max16065_update_device(struct device *dev)
index 1c8c981..1539878 100644 (file)
@@ -82,25 +82,6 @@ static inline int sht21_rh_ticks_to_per_cent_mille(int ticks)
        return ((15625 * ticks) >> 13) - 6000;
 }
 
-/**
- * sht21_read_word_data() - read word from register
- * @client: I2C client device
- * @reg: I2C command byte
- *
- * Returns value, negative errno on error.
- */
-static inline int sht21_read_word_data(struct i2c_client *client, u8 reg)
-{
-       int ret = i2c_smbus_read_word_data(client, reg);
-       if (ret < 0)
-               return ret;
-       /*
-        * SMBus specifies low byte first, but the SHT21 returns MSB
-        * first, so we have to swab16 the values
-        */
-       return swab16(ret);
-}
-
 /**
  * sht21_update_measurements() - get updated measurements from device
  * @client: I2C client device
@@ -119,12 +100,13 @@ static int sht21_update_measurements(struct i2c_client *client)
         * maximum two measurements per second at 12bit accuracy shall be made.
         */
        if (time_after(jiffies, sht21->last_update + HZ / 2) || !sht21->valid) {
-               ret = sht21_read_word_data(client, SHT21_TRIG_T_MEASUREMENT_HM);
+               ret = i2c_smbus_read_word_swapped(client,
+                                                 SHT21_TRIG_T_MEASUREMENT_HM);
                if (ret < 0)
                        goto out;
                sht21->temperature = sht21_temp_ticks_to_millicelsius(ret);
-               ret = sht21_read_word_data(client,
-                                       SHT21_TRIG_RH_MEASUREMENT_HM);
+               ret = i2c_smbus_read_word_swapped(client,
+                                                 SHT21_TRIG_RH_MEASUREMENT_HM);
                if (ret < 0)
                        goto out;
                sht21->humidity = sht21_rh_ticks_to_per_cent_mille(ret);
index 425df5b..4116381 100644 (file)
@@ -214,33 +214,26 @@ static int smm665_read_adc(struct smm665_data *data, int adc)
         *
         * Neither i2c_smbus_read_byte() nor
         * i2c_smbus_read_block_data() worked here,
-        * so use i2c_smbus_read_word_data() instead.
+        * so use i2c_smbus_read_word_swapped() instead.
         * We could also try to use i2c_master_recv(),
         * but that is not always supported.
         */
-       rv = i2c_smbus_read_word_data(client, 0);
+       rv = i2c_smbus_read_word_swapped(client, 0);
        if (rv < 0) {
                dev_dbg(&client->dev, "Failed to read ADC value: error %d", rv);
                return -1;
        }
        /*
         * Validate/verify readback adc channel (in bit 11..14).
-        * High byte is in lower 8 bit of rv, so only shift by 3.
         */
-       radc = (rv >> 3) & 0x0f;
+       radc = (rv >> 11) & 0x0f;
        if (radc != adc) {
                dev_dbg(&client->dev, "Unexpected RADC: Expected %d got %d",
                        adc, radc);
                return -EIO;
        }
-       /*
-        * Chip replies with H/L, while SMBus expects L/H.
-        * Thus, byte order is reversed, and we have to swap
-        * the result.
-        */
-       rv = swab16(rv) & SMM665_ADC_MASK;
 
-       return rv;
+       return rv & SMM665_ADC_MASK;
 }
 
 static struct smm665_data *smm665_update_device(struct device *dev)
index 9fb7516..65c88ff 100644 (file)
@@ -113,7 +113,7 @@ struct smsc47b397_data {
        u8 temp[4];
 };
 
-static int smsc47b397_read_value(struct smsc47b397_datadata, u8 reg)
+static int smsc47b397_read_value(struct smsc47b397_data *data, u8 reg)
 {
        int res;
 
@@ -265,7 +265,8 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev)
                return -EBUSY;
        }
 
-       if (!(data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) {
+       data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL);
+       if (!data) {
                err = -ENOMEM;
                goto error_release;
        }
@@ -276,7 +277,8 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev)
        mutex_init(&data->update_lock);
        platform_set_drvdata(pdev, data);
 
-       if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group)))
+       err = sysfs_create_group(&dev->kobj, &smsc47b397_group);
+       if (err)
                goto error_free;
 
        data->hwmon_dev = hwmon_device_register(dev);
@@ -345,7 +347,7 @@ static int __init smsc47b397_find(unsigned short *addr)
        superio_enter();
        id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
 
-       switch(id) {
+       switch (id) {
        case 0x81:
                name = "SCH5307-NS";
                break;
@@ -379,7 +381,8 @@ static int __init smsc47b397_init(void)
        unsigned short address;
        int ret;
 
-       if ((ret = smsc47b397_find(&address)))
+       ret = smsc47b397_find(&address);
+       if (ret)
                return ret;
 
        ret = platform_driver_register(&smsc47b397_driver);
index 5bd1949..643aa8c 100644 (file)
@@ -55,19 +55,6 @@ struct tmp102 {
        int temp[3];
 };
 
-/* SMBus specifies low byte first, but the TMP102 returns high byte first,
- * so we have to swab16 the values */
-static inline int tmp102_read_reg(struct i2c_client *client, u8 reg)
-{
-       int result = i2c_smbus_read_word_data(client, reg);
-       return result < 0 ? result : swab16(result);
-}
-
-static inline int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val)
-{
-       return i2c_smbus_write_word_data(client, reg, swab16(val));
-}
-
 /* convert left adjusted 13-bit TMP102 register value to milliCelsius */
 static inline int tmp102_reg_to_mC(s16 val)
 {
@@ -94,7 +81,8 @@ static struct tmp102 *tmp102_update_device(struct i2c_client *client)
        if (time_after(jiffies, tmp102->last_update + HZ / 3)) {
                int i;
                for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) {
-                       int status = tmp102_read_reg(client, tmp102_reg[i]);
+                       int status = i2c_smbus_read_word_swapped(client,
+                                                                tmp102_reg[i]);
                        if (status > -1)
                                tmp102->temp[i] = tmp102_reg_to_mC(status);
                }
@@ -130,8 +118,8 @@ static ssize_t tmp102_set_temp(struct device *dev,
 
        mutex_lock(&tmp102->lock);
        tmp102->temp[sda->index] = val;
-       status = tmp102_write_reg(client, tmp102_reg[sda->index],
-                                 tmp102_mC_to_reg(val));
+       status = i2c_smbus_write_word_swapped(client, tmp102_reg[sda->index],
+                                             tmp102_mC_to_reg(val));
        mutex_unlock(&tmp102->lock);
        return status ? : count;
 }
@@ -178,18 +166,19 @@ static int __devinit tmp102_probe(struct i2c_client *client,
        }
        i2c_set_clientdata(client, tmp102);
 
-       status = tmp102_read_reg(client, TMP102_CONF_REG);
+       status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
        if (status < 0) {
                dev_err(&client->dev, "error reading config register\n");
                goto fail_free;
        }
        tmp102->config_orig = status;
-       status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG);
+       status = i2c_smbus_write_word_swapped(client, TMP102_CONF_REG,
+                                             TMP102_CONFIG);
        if (status < 0) {
                dev_err(&client->dev, "error writing config register\n");
                goto fail_restore_config;
        }
-       status = tmp102_read_reg(client, TMP102_CONF_REG);
+       status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
        if (status < 0) {
                dev_err(&client->dev, "error reading config register\n");
                goto fail_restore_config;
@@ -222,7 +211,8 @@ static int __devinit tmp102_probe(struct i2c_client *client,
 fail_remove_sysfs:
        sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group);
 fail_restore_config:
-       tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig);
+       i2c_smbus_write_word_swapped(client, TMP102_CONF_REG,
+                                    tmp102->config_orig);
 fail_free:
        kfree(tmp102);
 
@@ -240,10 +230,10 @@ static int __devexit tmp102_remove(struct i2c_client *client)
        if (tmp102->config_orig & TMP102_CONF_SD) {
                int config;
 
-               config = tmp102_read_reg(client, TMP102_CONF_REG);
+               config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
                if (config >= 0)
-                       tmp102_write_reg(client, TMP102_CONF_REG,
-                                        config | TMP102_CONF_SD);
+                       i2c_smbus_write_word_swapped(client, TMP102_CONF_REG,
+                                                    config | TMP102_CONF_SD);
        }
 
        kfree(tmp102);
@@ -257,12 +247,12 @@ static int tmp102_suspend(struct device *dev)
        struct i2c_client *client = to_i2c_client(dev);
        int config;
 
-       config = tmp102_read_reg(client, TMP102_CONF_REG);
+       config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
        if (config < 0)
                return config;
 
        config |= TMP102_CONF_SD;
-       return tmp102_write_reg(client, TMP102_CONF_REG, config);
+       return i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config);
 }
 
 static int tmp102_resume(struct device *dev)
@@ -270,12 +260,12 @@ static int tmp102_resume(struct device *dev)
        struct i2c_client *client = to_i2c_client(dev);
        int config;
 
-       config = tmp102_read_reg(client, TMP102_CONF_REG);
+       config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG);
        if (config < 0)
                return config;
 
        config &= ~TMP102_CONF_SD;
-       return tmp102_write_reg(client, TMP102_CONF_REG, config);
+       return i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config);
 }
 
 static const struct dev_pm_ops tmp102_dev_pm_ops = {
index 98aab4b..483cb26 100644 (file)
@@ -1,7 +1,7 @@
 /*
     w83627ehf - Driver for the hardware monitoring functionality of
                the Winbond W83627EHF Super-I/O chip
-    Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
+    Copyright (C) 2005-2011  Jean Delvare <khali@linux-fr.org>
     Copyright (C) 2006  Yuan Mu (Winbond),
                        Rudolf Marek <r.marek@assembler.cz>
                        David Hubbard <david.c.hubbard@gmail.com>
@@ -39,6 +39,7 @@
                                               0x8860 0xa1
     w83627dhg    9      5       4       3      0xa020 0xc1    0x5ca3
     w83627dhg-p  9      5       4       3      0xb070 0xc1    0x5ca3
+    w83627uhg    8      2       2       2      0xa230 0xc1    0x5ca3
     w83667hg     9      5       3       3      0xa510 0xc1    0x5ca3
     w83667hg-b   9      5       3       4      0xb350 0xc1    0x5ca3
     nct6775f     9      4       3       9      0xb470 0xc1    0x5ca3
 #include <linux/io.h>
 #include "lm75.h"
 
-enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg, w83667hg_b, nct6775,
-       nct6776 };
+enum kinds {
+       w83627ehf, w83627dhg, w83627dhg_p, w83627uhg,
+       w83667hg, w83667hg_b, nct6775, nct6776,
+};
 
 /* used to set data->name = w83627ehf_device_names[data->sio_kind] */
 static const char * const w83627ehf_device_names[] = {
        "w83627ehf",
        "w83627dhg",
        "w83627dhg",
+       "w83627uhg",
        "w83667hg",
        "w83667hg",
        "nct6775",
@@ -104,6 +108,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
 #define SIO_W83627EHG_ID       0x8860
 #define SIO_W83627DHG_ID       0xa020
 #define SIO_W83627DHG_P_ID     0xb070
+#define SIO_W83627UHG_ID       0xa230
 #define SIO_W83667HG_ID                0xa510
 #define SIO_W83667HG_B_ID      0xb350
 #define SIO_NCT6775_ID         0xb470
@@ -388,18 +393,23 @@ div_from_reg(u8 reg)
        return 1 << reg;
 }
 
-/* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */
-
-static u8 scale_in[10] = { 8, 8, 16, 16, 8, 8, 8, 16, 16, 8 };
+/* Some of the voltage inputs have internal scaling, the tables below
+ * contain 8 (the ADC LSB in mV) * scaling factor * 100 */
+static const u16 scale_in_common[10] = {
+       800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800
+};
+static const u16 scale_in_w83627uhg[9] = {
+       800, 800, 3328, 3424, 800, 800, 0, 3328, 3400
+};
 
-static inline long in_from_reg(u8 reg, u8 nr)
+static inline long in_from_reg(u8 reg, u8 nr, const u16 *scale_in)
 {
-       return reg * scale_in[nr];
+       return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
 }
 
-static inline u8 in_to_reg(u32 val, u8 nr)
+static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scale_in)
 {
-       return SENSORS_LIMIT(((val + (scale_in[nr] / 2)) / scale_in[nr]), 0,
+       return SENSORS_LIMIT(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0,
                             255);
 }
 
@@ -430,6 +440,7 @@ struct w83627ehf_data {
        const u16 *REG_FAN_STOP_TIME;
        const u16 *REG_FAN_MAX_OUTPUT;
        const u16 *REG_FAN_STEP_OUTPUT;
+       const u16 *scale_in;
 
        unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
        unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
@@ -481,7 +492,8 @@ struct w83627ehf_data {
        u8 vrm;
 
        u16 have_temp;
-       u8 in6_skip;
+       u8 in6_skip:1;
+       u8 temp3_val_only:1;
 };
 
 struct w83627ehf_sio_data {
@@ -907,7 +919,8 @@ show_##reg(struct device *dev, struct device_attribute *attr, \
        struct sensor_device_attribute *sensor_attr = \
                to_sensor_dev_attr(attr); \
        int nr = sensor_attr->index; \
-       return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr)); \
+       return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr, \
+                      data->scale_in)); \
 }
 show_in_reg(in)
 show_in_reg(in_min)
@@ -928,7 +941,7 @@ store_in_##reg(struct device *dev, struct device_attribute *attr, \
        if (err < 0) \
                return err; \
        mutex_lock(&data->update_lock); \
-       data->in_##reg[nr] = in_to_reg(val, nr); \
+       data->in_##reg[nr] = in_to_reg(val, nr, data->scale_in); \
        w83627ehf_write_value(data, W83627EHF_REG_IN_##REG(nr), \
                              data->in_##reg[nr]); \
        mutex_unlock(&data->update_lock); \
@@ -1617,25 +1630,28 @@ static struct sensor_device_attribute sda_sf3_arrays_fan4[] = {
                    store_fan_step_output, 3),
 };
 
+static struct sensor_device_attribute sda_sf3_arrays_fan3[] = {
+       SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
+                   store_fan_stop_time, 2),
+       SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
+                   store_fan_start_output, 2),
+       SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
+                   store_fan_stop_output, 2),
+};
+
 static struct sensor_device_attribute sda_sf3_arrays[] = {
        SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
                    store_fan_stop_time, 0),
        SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
                    store_fan_stop_time, 1),
-       SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time,
-                   store_fan_stop_time, 2),
        SENSOR_ATTR(pwm1_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
                    store_fan_start_output, 0),
        SENSOR_ATTR(pwm2_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
                    store_fan_start_output, 1),
-       SENSOR_ATTR(pwm3_start_output, S_IWUSR | S_IRUGO, show_fan_start_output,
-                   store_fan_start_output, 2),
        SENSOR_ATTR(pwm1_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
                    store_fan_stop_output, 0),
        SENSOR_ATTR(pwm2_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
                    store_fan_stop_output, 1),
-       SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
-                   store_fan_stop_output, 2),
 };
 
 
@@ -1728,6 +1744,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
                    data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff)
                        device_remove_file(dev, &attr->dev_attr);
        }
+       for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++)
+               device_remove_file(dev, &sda_sf3_arrays_fan3[i].dev_attr);
        for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
                device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
        for (i = 0; i < data->in_num; i++) {
@@ -1756,6 +1774,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
                        continue;
                device_remove_file(dev, &sda_temp_input[i].dev_attr);
                device_remove_file(dev, &sda_temp_label[i].dev_attr);
+               if (i == 2 && data->temp3_val_only)
+                       continue;
                device_remove_file(dev, &sda_temp_max[i].dev_attr);
                device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
                if (i > 2)
@@ -1808,11 +1828,21 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data,
        case w83627ehf:
                diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
                break;
+       case w83627uhg:
+               diode = 0x00;
+               break;
        default:
                diode = 0x70;
        }
        for (i = 0; i < 3; i++) {
-               if ((tmp & (0x02 << i)))
+               const char *label = data->temp_label[data->temp_src[i]];
+
+               /* Digital source overrides analog type */
+               if (strncmp(label, "PECI", 4) == 0)
+                       data->temp_type[i] = 6;
+               else if (strncmp(label, "AMD", 3) == 0)
+                       data->temp_type[i] = 5;
+               else if ((tmp & (0x02 << i)))
                        data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3;
                else
                        data->temp_type[i] = 4; /* thermistor */
@@ -1845,12 +1875,32 @@ static void w82627ehf_swap_tempreg(struct w83627ehf_data *data,
        data->reg_temp_config[r2] = tmp;
 }
 
+static void __devinit
+w83627ehf_set_temp_reg_ehf(struct w83627ehf_data *data, int n_temp)
+{
+       int i;
+
+       for (i = 0; i < n_temp; i++) {
+               data->reg_temp[i] = W83627EHF_REG_TEMP[i];
+               data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i];
+               data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i];
+               data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i];
+       }
+}
+
 static void __devinit
 w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
                           struct w83627ehf_data *data)
 {
        int fan3pin, fan4pin, fan4min, fan5pin, regval;
 
+       /* The W83627UHG is simple, only two fan inputs, no config */
+       if (sio_data->kind == w83627uhg) {
+               data->has_fan = 0x03; /* fan1 and fan2 */
+               data->has_fan_min = 0x03;
+               return;
+       }
+
        superio_enter(sio_data->sioreg);
 
        /* fan4 and fan5 share some pins with the GPIO and serial flash */
@@ -1942,23 +1992,24 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
 
        /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
        data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
-       /* 667HG, NCT6775F, and NCT6776F have 3 pwms */
-       data->pwm_num = (sio_data->kind == w83667hg
-                        || sio_data->kind == w83667hg_b
-                        || sio_data->kind == nct6775
-                        || sio_data->kind == nct6776) ? 3 : 4;
+       /* 667HG, NCT6775F, and NCT6776F have 3 pwms, and 627UHG has only 2 */
+       switch (sio_data->kind) {
+       default:
+               data->pwm_num = 4;
+               break;
+       case w83667hg:
+       case w83667hg_b:
+       case nct6775:
+       case nct6776:
+               data->pwm_num = 3;
+               break;
+       case w83627uhg:
+               data->pwm_num = 2;
+               break;
+       }
 
+       /* Default to 3 temperature inputs, code below will adjust as needed */
        data->have_temp = 0x07;
-       /* Check temp3 configuration bit for 667HG */
-       if (sio_data->kind == w83667hg) {
-               u8 reg;
-
-               reg = w83627ehf_read_value(data, W83627EHF_REG_TEMP_CONFIG[2]);
-               if (reg & 0x01)
-                       data->have_temp &= ~(1 << 2);
-               else
-                       data->in6_skip = 1;     /* either temp3 or in6 */
-       }
 
        /* Deal with temperature register setup first. */
        if (sio_data->kind == nct6775 || sio_data->kind == nct6776) {
@@ -2035,16 +2086,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
        } else if (sio_data->kind == w83667hg_b) {
                u8 reg;
 
+               w83627ehf_set_temp_reg_ehf(data, 4);
+
                /*
                 * Temperature sources are selected with bank 0, registers 0x49
                 * and 0x4a.
                 */
-               for (i = 0; i < ARRAY_SIZE(W83627EHF_REG_TEMP); i++) {
-                       data->reg_temp[i] = W83627EHF_REG_TEMP[i];
-                       data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i];
-                       data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i];
-                       data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i];
-               }
                reg = w83627ehf_read_value(data, 0x4a);
                data->temp_src[0] = reg >> 5;
                reg = w83627ehf_read_value(data, 0x49);
@@ -2077,14 +2124,61 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
                    || (data->temp_src[3] == 2 && (data->have_temp & (1 << 3))))
                        data->in6_skip = 1;
 
+               data->temp_label = w83667hg_b_temp_label;
+       } else if (sio_data->kind == w83627uhg) {
+               u8 reg;
+
+               w83627ehf_set_temp_reg_ehf(data, 3);
+
+               /*
+                * Temperature sources for temp1 and temp2 are selected with
+                * bank 0, registers 0x49 and 0x4a.
+                */
+               data->temp_src[0] = 0;  /* SYSTIN */
+               reg = w83627ehf_read_value(data, 0x49) & 0x07;
+               /* Adjust to have the same mapping as other source registers */
+               if (reg == 0)
+                       data->temp_src[1]++;
+               else if (reg >= 2 && reg <= 5)
+                       data->temp_src[1] += 2;
+               else    /* should never happen */
+                       data->have_temp &= ~(1 << 1);
+               reg = w83627ehf_read_value(data, 0x4a);
+               data->temp_src[2] = reg >> 5;
+
+               /*
+                * Skip temp3 if source is invalid or the same as temp1
+                * or temp2.
+                */
+               if (data->temp_src[2] == 2 || data->temp_src[2] == 3 ||
+                   data->temp_src[2] == data->temp_src[0] ||
+                   ((data->have_temp & (1 << 1)) &&
+                    data->temp_src[2] == data->temp_src[1]))
+                       data->have_temp &= ~(1 << 2);
+               else
+                       data->temp3_val_only = 1;       /* No limit regs */
+
+               data->in6_skip = 1;                     /* No VIN3 */
+
                data->temp_label = w83667hg_b_temp_label;
        } else {
+               w83627ehf_set_temp_reg_ehf(data, 3);
+
                /* Temperature sources are fixed */
-               for (i = 0; i < 3; i++) {
-                       data->reg_temp[i] = W83627EHF_REG_TEMP[i];
-                       data->reg_temp_over[i] = W83627EHF_REG_TEMP_OVER[i];
-                       data->reg_temp_hyst[i] = W83627EHF_REG_TEMP_HYST[i];
-                       data->reg_temp_config[i] = W83627EHF_REG_TEMP_CONFIG[i];
+
+               if (sio_data->kind == w83667hg) {
+                       u8 reg;
+
+                       /*
+                        * Chip supports either AUXTIN or VIN3. Try to find
+                        * out which one.
+                        */
+                       reg = w83627ehf_read_value(data,
+                                               W83627EHF_REG_TEMP_CONFIG[2]);
+                       if (reg & 0x01)
+                               data->have_temp &= ~(1 << 2);
+                       else
+                               data->in6_skip = 1;
                }
        }
 
@@ -2144,6 +2238,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
                  W83627EHF_REG_FAN_STEP_OUTPUT_COMMON;
        }
 
+       /* Setup input voltage scaling factors */
+       if (sio_data->kind == w83627uhg)
+               data->scale_in = scale_in_w83627uhg;
+       else
+               data->scale_in = scale_in_common;
+
        /* Initialize the chip */
        w83627ehf_init_device(data, sio_data->kind);
 
@@ -2160,7 +2260,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
                err = device_create_file(dev, &dev_attr_cpu0_vid);
                if (err)
                        goto exit_release;
-       } else {
+       } else if (sio_data->kind != w83627uhg) {
                superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
                if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
                        /* Set VID input sensibility if needed. In theory the
@@ -2250,7 +2350,14 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
                                goto exit_remove;
                }
        }
-       /* if fan4 is enabled create the sf3 files for it */
+       /* if fan3 and fan4 are enabled create the sf3 files for them */
+       if ((data->has_fan & (1 << 2)) && data->pwm_num >= 3)
+               for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan3); i++) {
+                       err = device_create_file(dev,
+                                       &sda_sf3_arrays_fan3[i].dev_attr);
+                       if (err)
+                               goto exit_remove;
+               }
        if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
                for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
                        err = device_create_file(dev,
@@ -2318,6 +2425,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
                        if (err)
                                goto exit_remove;
                }
+               if (i == 2 && data->temp3_val_only)
+                       continue;
                if (data->reg_temp_over[i]) {
                        err = device_create_file(dev,
                                &sda_temp_max[i].dev_attr);
@@ -2401,6 +2510,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
        static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
        static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
        static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P";
+       static const char __initdata sio_name_W83627UHG[] = "W83627UHG";
        static const char __initdata sio_name_W83667HG[] = "W83667HG";
        static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B";
        static const char __initdata sio_name_NCT6775[] = "NCT6775F";
@@ -2433,6 +2543,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
                sio_data->kind = w83627dhg_p;
                sio_name = sio_name_W83627DHG_P;
                break;
+       case SIO_W83627UHG_ID:
+               sio_data->kind = w83627uhg;
+               sio_name = sio_name_W83627UHG;
+               break;
        case SIO_W83667HG_ID:
                sio_data->kind = w83667hg;
                sio_name = sio_name_W83667HG;
index eed43a0..65b685e 100644 (file)
@@ -1245,17 +1245,17 @@ w83781d_read_value_i2c(struct w83781d_data *data, u16 reg)
                /* convert from ISA to LM75 I2C addresses */
                switch (reg & 0xff) {
                case 0x50:      /* TEMP */
-                       res = swab16(i2c_smbus_read_word_data(cl, 0));
+                       res = i2c_smbus_read_word_swapped(cl, 0);
                        break;
                case 0x52:      /* CONFIG */
                        res = i2c_smbus_read_byte_data(cl, 1);
                        break;
                case 0x53:      /* HYST */
-                       res = swab16(i2c_smbus_read_word_data(cl, 2));
+                       res = i2c_smbus_read_word_swapped(cl, 2);
                        break;
                case 0x55:      /* OVER */
                default:
-                       res = swab16(i2c_smbus_read_word_data(cl, 3));
+                       res = i2c_smbus_read_word_swapped(cl, 3);
                        break;
                }
        }
@@ -1289,10 +1289,10 @@ w83781d_write_value_i2c(struct w83781d_data *data, u16 reg, u16 value)
                        i2c_smbus_write_byte_data(cl, 1, value & 0xff);
                        break;
                case 0x53:      /* HYST */
-                       i2c_smbus_write_word_data(cl, 2, swab16(value));
+                       i2c_smbus_write_word_swapped(cl, 2, value);
                        break;
                case 0x55:      /* OVER */
-                       i2c_smbus_write_word_data(cl, 3, swab16(value));
+                       i2c_smbus_write_word_swapped(cl, 3, value);
                        break;
                }
        }
index ab876f9..ed9a989 100644 (file)
@@ -146,7 +146,7 @@ static int mthca_buddy_init(struct mthca_buddy *buddy, int max_order)
 
        buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *),
                              GFP_KERNEL);
-       buddy->num_free = kzalloc((buddy->max_order + 1) * sizeof (int *),
+       buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free,
                                  GFP_KERNEL);
        if (!buddy->bits || !buddy->num_free)
                goto err_out;
index afaf4ac..894afac 100644 (file)
@@ -271,13 +271,9 @@ int qib_make_rc_req(struct qib_qp *qp)
                        goto bail;
                }
                wqe = get_swqe_ptr(qp, qp->s_last);
-               while (qp->s_last != qp->s_acked) {
-                       qib_send_complete(qp, wqe, IB_WC_SUCCESS);
-                       if (++qp->s_last >= qp->s_size)
-                               qp->s_last = 0;
-                       wqe = get_swqe_ptr(qp, qp->s_last);
-               }
-               qib_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
+               qib_send_complete(qp, wqe, qp->s_last != qp->s_acked ?
+                       IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR);
+               /* will get called again */
                goto done;
        }
 
index 84e8c29..c42b8f3 100644 (file)
@@ -151,7 +151,6 @@ int iser_initialize_task_headers(struct iscsi_task *task,
        tx_desc->tx_sg[0].length = ISER_HEADERS_LEN;
        tx_desc->tx_sg[0].lkey   = device->mr->lkey;
 
-       iser_task->headers_initialized  = 1;
        iser_task->iser_conn            = iser_conn;
        return 0;
 }
@@ -166,8 +165,7 @@ iscsi_iser_task_init(struct iscsi_task *task)
 {
        struct iscsi_iser_task *iser_task = task->dd_data;
 
-       if (!iser_task->headers_initialized)
-               if (iser_initialize_task_headers(task, &iser_task->desc))
+       if (iser_initialize_task_headers(task, &iser_task->desc))
                        return -ENOMEM;
 
        /* mgmt task */
@@ -278,6 +276,13 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
 static void iscsi_iser_cleanup_task(struct iscsi_task *task)
 {
        struct iscsi_iser_task *iser_task = task->dd_data;
+       struct iser_tx_desc     *tx_desc = &iser_task->desc;
+
+       struct iscsi_iser_conn *iser_conn = task->conn->dd_data;
+       struct iser_device     *device    = iser_conn->ib_conn->device;
+
+       ib_dma_unmap_single(device->ib_device,
+               tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
 
        /* mgmt tasks do not need special cleanup */
        if (!task->sc)
index db6f3ce..db7ea37 100644 (file)
@@ -257,7 +257,8 @@ struct iser_conn {
        struct list_head             conn_list;       /* entry in ig conn list */
 
        char                         *login_buf;
-       u64                          login_dma;
+       char                         *login_req_buf, *login_resp_buf;
+       u64                          login_req_dma, login_resp_dma;
        unsigned int                 rx_desc_head;
        struct iser_rx_desc          *rx_descs;
        struct ib_recv_wr            rx_wr[ISER_MIN_POSTED_RX];
@@ -277,7 +278,6 @@ struct iscsi_iser_task {
        struct iser_regd_buf         rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */
        struct iser_data_buf         data[ISER_DIRS_NUM];     /* orig. data des*/
        struct iser_data_buf         data_copy[ISER_DIRS_NUM];/* contig. copy  */
-       int                          headers_initialized;
 };
 
 struct iser_page_vec {
index f299de6..a607542 100644 (file)
@@ -221,8 +221,14 @@ void iser_free_rx_descriptors(struct iser_conn *ib_conn)
        struct iser_device *device = ib_conn->device;
 
        if (ib_conn->login_buf) {
-               ib_dma_unmap_single(device->ib_device, ib_conn->login_dma,
-                       ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
+               if (ib_conn->login_req_dma)
+                       ib_dma_unmap_single(device->ib_device,
+                               ib_conn->login_req_dma,
+                               ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
+               if (ib_conn->login_resp_dma)
+                       ib_dma_unmap_single(device->ib_device,
+                               ib_conn->login_resp_dma,
+                               ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
                kfree(ib_conn->login_buf);
        }
 
@@ -394,6 +400,7 @@ int iser_send_control(struct iscsi_conn *conn,
        unsigned long data_seg_len;
        int err = 0;
        struct iser_device *device;
+       struct iser_conn *ib_conn = iser_conn->ib_conn;
 
        /* build the tx desc regd header and add it to the tx desc dto */
        mdesc->type = ISCSI_TX_CONTROL;
@@ -409,9 +416,19 @@ int iser_send_control(struct iscsi_conn *conn,
                        iser_err("data present on non login task!!!\n");
                        goto send_control_error;
                }
-               memcpy(iser_conn->ib_conn->login_buf, task->data,
+
+               ib_dma_sync_single_for_cpu(device->ib_device,
+                       ib_conn->login_req_dma, task->data_count,
+                       DMA_TO_DEVICE);
+
+               memcpy(iser_conn->ib_conn->login_req_buf, task->data,
                                                        task->data_count);
-               tx_dsg->addr    = iser_conn->ib_conn->login_dma;
+
+               ib_dma_sync_single_for_device(device->ib_device,
+                       ib_conn->login_req_dma, task->data_count,
+                       DMA_TO_DEVICE);
+
+               tx_dsg->addr    = iser_conn->ib_conn->login_req_dma;
                tx_dsg->length  = task->data_count;
                tx_dsg->lkey    = device->mr->lkey;
                mdesc->num_sge = 2;
@@ -445,8 +462,8 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
        int rx_buflen, outstanding, count, err;
 
        /* differentiate between login to all other PDUs */
-       if ((char *)rx_desc == ib_conn->login_buf) {
-               rx_dma = ib_conn->login_dma;
+       if ((char *)rx_desc == ib_conn->login_resp_buf) {
+               rx_dma = ib_conn->login_resp_dma;
                rx_buflen = ISER_RX_LOGIN_SIZE;
        } else {
                rx_dma = rx_desc->dma_addr;
@@ -473,7 +490,7 @@ void iser_rcv_completion(struct iser_rx_desc *rx_desc,
         * for the posted rx bufs refcount to become zero handles everything   */
        conn->ib_conn->post_recv_buf_count--;
 
-       if (rx_dma == ib_conn->login_dma)
+       if (rx_dma == ib_conn->login_resp_dma)
                return;
 
        outstanding = ib_conn->post_recv_buf_count;
index ede1475..e28877c 100644 (file)
@@ -155,20 +155,39 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn)
 {
        struct iser_device      *device;
        struct ib_qp_init_attr  init_attr;
-       int                     ret = -ENOMEM;
+       int                     req_err, resp_err, ret = -ENOMEM;
        struct ib_fmr_pool_param params;
 
        BUG_ON(ib_conn->device == NULL);
 
        device = ib_conn->device;
 
-       ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL);
+       ib_conn->login_buf = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN +
+                                       ISER_RX_LOGIN_SIZE, GFP_KERNEL);
        if (!ib_conn->login_buf)
                goto out_err;
 
-       ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device,
-                               (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE,
-                               DMA_FROM_DEVICE);
+       ib_conn->login_req_buf  = ib_conn->login_buf;
+       ib_conn->login_resp_buf = ib_conn->login_buf + ISCSI_DEF_MAX_RECV_SEG_LEN;
+
+       ib_conn->login_req_dma = ib_dma_map_single(ib_conn->device->ib_device,
+                               (void *)ib_conn->login_req_buf,
+                               ISCSI_DEF_MAX_RECV_SEG_LEN, DMA_TO_DEVICE);
+
+       ib_conn->login_resp_dma = ib_dma_map_single(ib_conn->device->ib_device,
+                               (void *)ib_conn->login_resp_buf,
+                               ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
+
+       req_err  = ib_dma_mapping_error(device->ib_device, ib_conn->login_req_dma);
+       resp_err = ib_dma_mapping_error(device->ib_device, ib_conn->login_resp_dma);
+
+       if (req_err || resp_err) {
+               if (req_err)
+                       ib_conn->login_req_dma = 0;
+               if (resp_err)
+                       ib_conn->login_resp_dma = 0;
+               goto out_err;
+       }
 
        ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) +
                                    (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)),
@@ -658,11 +677,11 @@ int iser_post_recvl(struct iser_conn *ib_conn)
        struct ib_sge     sge;
        int ib_ret;
 
-       sge.addr   = ib_conn->login_dma;
+       sge.addr   = ib_conn->login_resp_dma;
        sge.length = ISER_RX_LOGIN_SIZE;
        sge.lkey   = ib_conn->device->mr->lkey;
 
-       rx_wr.wr_id   = (unsigned long)ib_conn->login_buf;
+       rx_wr.wr_id   = (unsigned long)ib_conn->login_resp_buf;
        rx_wr.sg_list = &sge;
        rx_wr.num_sge = 1;
        rx_wr.next    = NULL;
index cf7214e..38019ba 100644 (file)
@@ -11,4 +11,4 @@ ccflags-y += -Idrivers/media/dvb/frontends/
 ccflags-y += -Idrivers/media/common/tuners/
 
 # For the staging CI driver cxd2099
-ccflags-y += -Idrivers/staging/cxd2099/
+ccflags-y += -Idrivers/staging/media/cxd2099/
index 7d0710b..26c8b9e 100644 (file)
@@ -102,6 +102,7 @@ obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
 
 dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
 obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
+obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
 obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
 
 ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
index 2ad33ba..2d08c9b 100644 (file)
@@ -37,6 +37,7 @@
 #define USB_VID_HAUPPAUGE                      0x2040
 #define USB_VID_HYPER_PALTEK                   0x1025
 #define USB_VID_INTEL                          0x8086
+#define USB_VID_ITETECH                                0x048d
 #define USB_VID_KWORLD                         0xeb2a
 #define USB_VID_KWORLD_2                       0x1b80
 #define USB_VID_KYE                            0x0458
 #define USB_PID_GRANDTEC_DVBT_USB_COLD                 0x0fa0
 #define USB_PID_GRANDTEC_DVBT_USB_WARM                 0x0fa1
 #define USB_PID_INTEL_CE9500                           0x9500
+#define USB_PID_ITETECH_IT9135                         0x9135
 #define USB_PID_KWORLD_399U                            0xe399
 #define USB_PID_KWORLD_399U_2                          0xe400
 #define USB_PID_KWORLD_395U                            0xe396
index f027a2c..c462261 100644 (file)
@@ -60,6 +60,17 @@ struct it913x_state {
        u8 id;
 };
 
+struct ite_config {
+       u8 chip_ver;
+       u16 chip_type;
+       u32 firmware;
+       u8 tuner_id_0;
+       u8 tuner_id_1;
+       u8 dual_mode;
+};
+
+struct ite_config it913x_config;
+
 static int it913x_bulk_write(struct usb_device *dev,
                                u8 *snd, int len, u8 pipe)
 {
@@ -191,18 +202,23 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg)
 static u32 it913x_query(struct usb_device *udev, u8 pro)
 {
        int ret;
-       u32 res = 0;
        u8 data[4];
        ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ,
-               0x1222, 0, &data[0], 1);
-       if (data[0] == 0x1) {
-               ret = it913x_io(udev, READ_SHORT, pro,
+               0x1222, 0, &data[0], 3);
+
+       it913x_config.chip_ver = data[0];
+       it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
+
+       info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver,
+               it913x_config.chip_type);
+
+       ret |= it913x_io(udev, READ_SHORT, pro,
                        CMD_QUERYINFO, 0, 0x1, &data[0], 4);
-               res = (data[0] << 24) + (data[1] << 16) +
+
+       it913x_config.firmware = (data[0] << 24) + (data[1] << 16) +
                        (data[2] << 8) + data[3];
-       }
 
-       return (ret < 0) ? 0 : res;
+       return (ret < 0) ? 0 : it913x_config.firmware;
 }
 
 static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
@@ -336,26 +352,35 @@ static int it913x_identify_state(struct usb_device *udev,
                int *cold)
 {
        int ret = 0, firm_no;
-       u8 reg, adap, ep, tun0, tun1;
+       u8 reg, remote;
 
        firm_no = it913x_return_status(udev);
 
-       ep = it913x_read_reg(udev, 0x49ac);
-       adap = it913x_read_reg(udev, 0x49c5);
-       tun0 = it913x_read_reg(udev, 0x49d0);
-       info("No. Adapters=%x Endpoints=%x Tuner Type=%x", adap, ep, tun0);
+       /* checnk for dual mode */
+       it913x_config.dual_mode =  it913x_read_reg(udev, 0x49c5);
+
+       /* TODO different remotes */
+       remote = it913x_read_reg(udev, 0x49ac); /* Remote */
+       if (remote == 0)
+               props->rc.core.rc_codes = NULL;
+
+       /* TODO at the moment tuner_id is always assigned to 0x38 */
+       it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0);
+
+       info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode
+               , remote, it913x_config.tuner_id_0);
 
        if (firm_no > 0) {
                *cold = 0;
                return 0;
        }
 
-       if (adap > 2) {
-               tun1 = it913x_read_reg(udev, 0x49e0);
+       if (it913x_config.dual_mode) {
+               it913x_config.tuner_id_1 = it913x_read_reg(udev, 0x49e0);
                ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1);
                ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1);
                ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1);
-               msleep(50); /* Delay noticed reset cycle ? */
+               msleep(50);
                ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0);
                msleep(50);
                reg = it913x_read_reg(udev, GPIOH1_O);
@@ -366,14 +391,19 @@ static int it913x_identify_state(struct usb_device *udev,
                                ret = it913x_wr_reg(udev, DEV_0,
                                        GPIOH1_O, 0x0);
                }
+               props->num_adapters = 2;
        } else
                props->num_adapters = 1;
 
        reg = it913x_read_reg(udev, IO_MUX_POWER_CLK);
 
-       ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
-
-       ret |= it913x_wr_reg(udev, DEV_0,  CLK_O_EN, 0x1);
+       if (it913x_config.dual_mode) {
+               ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
+               ret |= it913x_wr_reg(udev, DEV_0,  CLK_O_EN, 0x1);
+       } else {
+               ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0);
+               ret |= it913x_wr_reg(udev, DEV_0,  CLK_O_EN, 0x0);
+       }
 
        *cold = 1;
 
@@ -403,13 +433,11 @@ static int it913x_download_firmware(struct usb_device *udev,
                                        const struct firmware *fw)
 {
        int ret = 0, i;
-       u8 packet_size, dlen, tun1;
+       u8 packet_size, dlen;
        u8 *fw_data;
 
        packet_size = 0x29;
 
-       tun1 = it913x_read_reg(udev, 0x49e0);
-
        ret = it913x_wr_reg(udev, DEV_0,  I2C_CLK, I2C_CLK_100);
 
        info("FRM Starting Firmware Download");
@@ -444,11 +472,12 @@ static int it913x_download_firmware(struct usb_device *udev,
        ret |= it913x_wr_reg(udev, DEV_0,  I2C_CLK, I2C_CLK_400);
 
        /* Tuner function */
-       ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0);
+       if (it913x_config.dual_mode)
+               ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0);
 
        ret |= it913x_wr_reg(udev, DEV_0,  PADODPU, 0x0);
        ret |= it913x_wr_reg(udev, DEV_0,  AGC_O_D, 0x0);
-       if (tun1 > 0) {
+       if (it913x_config.dual_mode) {
                ret |= it913x_wr_reg(udev, DEV_1,  PADODPU, 0x0);
                ret |= it913x_wr_reg(udev, DEV_1,  AGC_O_D, 0x0);
        }
@@ -475,9 +504,28 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
        u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK);
        u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
        u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize;
+       u8 tuner_id, tuner_type;
+
+       if (adap->id == 0)
+               tuner_id = it913x_config.tuner_id_0;
+       else
+               tuner_id = it913x_config.tuner_id_1;
+
+       /* TODO we always use IT9137 possible references here*/
+       /* Documentation suggests don't care */
+       switch (tuner_id) {
+       case 0x51:
+       case 0x52:
+       case 0x60:
+       case 0x61:
+       case 0x62:
+       default:
+       case 0x38:
+               tuner_type = IT9137;
+       }
 
        adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach,
-               &adap->dev->i2c_adap, adap_addr, adf, IT9137);
+               &adap->dev->i2c_adap, adap_addr, adf, tuner_type);
 
        if (adap->id == 0 && adap->fe_adap[0].fe) {
                ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1);
@@ -533,6 +581,7 @@ static int it913x_probe(struct usb_interface *intf,
 
 static struct usb_device_id it913x_table[] = {
        { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) },
+       { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) },
        {}              /* Terminating entry */
 };
 
@@ -608,12 +657,14 @@ static struct dvb_usb_device_properties it913x_properties = {
                .rc_codes       = RC_MAP_KWORLD_315U,
        },
        .i2c_algo         = &it913x_i2c_algo,
-       .num_device_descs = 1,
+       .num_device_descs = 2,
        .devices = {
                {   "Kworld UB499-2T T09(IT9137)",
                        { &it913x_table[0], NULL },
                        },
-
+               {   "ITE 9135 Generic",
+                       { &it913x_table[1], NULL },
+                       },
        }
 };
 
@@ -647,5 +698,5 @@ module_exit(it913x_module_exit);
 
 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
 MODULE_DESCRIPTION("it913x USB 2 Driver");
-MODULE_VERSION("1.06");
+MODULE_VERSION("1.07");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c
new file mode 100644 (file)
index 0000000..d1f5837
--- /dev/null
@@ -0,0 +1,614 @@
+/*
+ *  mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "mxl111sf-demod.h"
+#include "mxl111sf-reg.h"
+
+/* debug */
+static int mxl111sf_demod_debug;
+module_param_named(debug, mxl111sf_demod_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
+
+#define mxl_dbg(fmt, arg...) \
+       if (mxl111sf_demod_debug) \
+               mxl_printk(KERN_DEBUG, fmt, ##arg)
+
+/* ------------------------------------------------------------------------ */
+
+struct mxl111sf_demod_state {
+       struct mxl111sf_state *mxl_state;
+
+       struct mxl111sf_demod_config *cfg;
+
+       struct dvb_frontend fe;
+};
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_demod_read_reg(struct mxl111sf_demod_state *state,
+                                  u8 addr, u8 *data)
+{
+       return (state->cfg->read_reg) ?
+               state->cfg->read_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static int mxl111sf_demod_write_reg(struct mxl111sf_demod_state *state,
+                                   u8 addr, u8 data)
+{
+       return (state->cfg->write_reg) ?
+               state->cfg->write_reg(state->mxl_state, addr, data) :
+               -EINVAL;
+}
+
+static
+int mxl111sf_demod_program_regs(struct mxl111sf_demod_state *state,
+                               struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
+{
+       return (state->cfg->program_regs) ?
+               state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
+               -EINVAL;
+}
+
+/* ------------------------------------------------------------------------ */
+/* TPS */
+
+static
+int mxl1x1sf_demod_get_tps_code_rate(struct mxl111sf_demod_state *state,
+                                    fe_code_rate_t *code_rate)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_CODE_RATE_TPS_REG, &val);
+       /* bit<2:0> - 000:1/2, 001:2/3, 010:3/4, 011:5/6, 100:7/8 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch (val & V6_CODE_RATE_TPS_MASK) {
+       case 0:
+               *code_rate = FEC_1_2;
+               break;
+       case 1:
+               *code_rate = FEC_2_3;
+               break;
+       case 2:
+               *code_rate = FEC_3_4;
+               break;
+       case 3:
+               *code_rate = FEC_5_6;
+               break;
+       case 4:
+               *code_rate = FEC_7_8;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_constellation(struct mxl111sf_demod_state *state,
+                                        fe_modulation_t *constellation)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val);
+       /* Constellation, 00 : QPSK, 01 : 16QAM, 10:64QAM */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) {
+       case 0:
+               *constellation = QPSK;
+               break;
+       case 1:
+               *constellation = QAM_16;
+               break;
+       case 2:
+               *constellation = QAM_64;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_guard_fft_mode(struct mxl111sf_demod_state *state,
+                                         fe_transmit_mode_t *fft_mode)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_MODE_TPS_REG, &val);
+       /* FFT Mode, 00:2K, 01:8K, 10:4K */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_PARAM_FFT_MODE_MASK) >> 2) {
+       case 0:
+               *fft_mode = TRANSMISSION_MODE_2K;
+               break;
+       case 1:
+               *fft_mode = TRANSMISSION_MODE_8K;
+               break;
+       case 2:
+               *fft_mode = TRANSMISSION_MODE_4K;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_guard_interval(struct mxl111sf_demod_state *state,
+                                         fe_guard_interval_t *guard)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_CP_TPS_REG, &val);
+       /* 00:1/32, 01:1/16, 10:1/8, 11:1/4 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_PARAM_GI_MASK) >> 4) {
+       case 0:
+               *guard = GUARD_INTERVAL_1_32;
+               break;
+       case 1:
+               *guard = GUARD_INTERVAL_1_16;
+               break;
+       case 2:
+               *guard = GUARD_INTERVAL_1_8;
+               break;
+       case 3:
+               *guard = GUARD_INTERVAL_1_4;
+               break;
+       }
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_hierarchy(struct mxl111sf_demod_state *state,
+                                    fe_hierarchy_t *hierarchy)
+{
+       u8 val;
+       int ret = mxl111sf_demod_read_reg(state, V6_TPS_HIERACHY_REG, &val);
+       /* bit<6:4> - 000:Non hierarchy, 001:1, 010:2, 011:4 */
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch ((val & V6_TPS_HIERARCHY_INFO_MASK) >> 6) {
+       case 0:
+               *hierarchy = HIERARCHY_NONE;
+               break;
+       case 1:
+               *hierarchy = HIERARCHY_1;
+               break;
+       case 2:
+               *hierarchy = HIERARCHY_2;
+               break;
+       case 3:
+               *hierarchy = HIERARCHY_4;
+               break;
+       }
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+/* LOCKS */
+
+static
+int mxl1x1sf_demod_get_sync_lock_status(struct mxl111sf_demod_state *state,
+                                       int *sync_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_SYNC_LOCK_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *sync_lock = (val & SYNC_LOCK_MASK) >> 4;
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_rs_lock_status(struct mxl111sf_demod_state *state,
+                                     int *rs_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_RS_LOCK_DET_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *rs_lock = (val & RS_LOCK_DET_MASK) >> 3;
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_tps_lock_status(struct mxl111sf_demod_state *state,
+                                      int *tps_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_TPS_LOCK_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *tps_lock = (val & V6_PARAM_TPS_LOCK_MASK) >> 6;
+fail:
+       return ret;
+}
+
+static
+int mxl1x1sf_demod_get_fec_lock_status(struct mxl111sf_demod_state *state,
+                                      int *fec_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_IRQ_STATUS_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *fec_lock = (val & IRQ_MASK_FEC_LOCK) >> 4;
+fail:
+       return ret;
+}
+
+#if 0
+static
+int mxl1x1sf_demod_get_cp_lock_status(struct mxl111sf_demod_state *state,
+                                     int *cp_lock)
+{
+       u8 val = 0;
+       int ret = mxl111sf_demod_read_reg(state, V6_CP_LOCK_DET_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+       *cp_lock = (val & V6_CP_LOCK_DET_MASK) >> 2;
+fail:
+       return ret;
+}
+#endif
+
+static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state)
+{
+       return mxl111sf_demod_write_reg(state, 0x0e, 0xff);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe,
+                                      struct dvb_frontend_parameters *param)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       int ret = 0;
+
+       struct mxl111sf_reg_ctrl_info phy_pll_patch[] = {
+               {0x00, 0xff, 0x01}, /* change page to 1 */
+               {0x40, 0xff, 0x05},
+               {0x40, 0xff, 0x01},
+               {0x41, 0xff, 0xca},
+               {0x41, 0xff, 0xc0},
+               {0x00, 0xff, 0x00}, /* change page to 0 */
+               {0,    0,    0}
+       };
+
+       mxl_dbg("()");
+
+       if (fe->ops.tuner_ops.set_params) {
+               ret = fe->ops.tuner_ops.set_params(fe, param);
+               if (mxl_fail(ret))
+                       goto fail;
+               msleep(50);
+       }
+       ret = mxl111sf_demod_program_regs(state, phy_pll_patch);
+       mxl_fail(ret);
+       msleep(50);
+       ret = mxl1x1sf_demod_reset_irq_status(state);
+       mxl_fail(ret);
+       msleep(100);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+#if 0
+/* resets TS Packet error count */
+/* After setting 7th bit of V5_PER_COUNT_RESET_REG, it should be reset to 0. */
+static
+int mxl1x1sf_demod_reset_packet_error_count(struct mxl111sf_demod_state *state)
+{
+       struct mxl111sf_reg_ctrl_info reset_per_count[] = {
+               {0x20, 0x01, 0x01},
+               {0x20, 0x01, 0x00},
+               {0,    0,    0}
+       };
+       return mxl111sf_demod_program_regs(state, reset_per_count);
+}
+#endif
+
+/* returns TS Packet error count */
+/* PER Count = FEC_PER_COUNT * (2 ** (FEC_PER_SCALE * 4)) */
+static int mxl111sf_demod_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       u32 fec_per_count, fec_per_scale;
+       u8 val;
+       int ret;
+
+       *ucblocks = 0;
+
+       /* FEC_PER_COUNT Register */
+       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_COUNT_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       fec_per_count = val;
+
+       /* FEC_PER_SCALE Register */
+       ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_SCALE_REG, &val);
+       if (mxl_fail(ret))
+               goto fail;
+
+       val &= V6_FEC_PER_SCALE_MASK;
+       val *= 4;
+
+       fec_per_scale = 1 << val;
+
+       fec_per_count *= fec_per_scale;
+
+       *ucblocks = fec_per_count;
+fail:
+       return ret;
+}
+
+#ifdef MXL111SF_DEMOD_ENABLE_CALCULATIONS
+/* FIXME: leaving this enabled breaks the build on some architectures,
+ * and we shouldn't have any floating point math in the kernel, anyway.
+ *
+ * These macros need to be re-written, but it's harmless to simply
+ * return zero for now. */
+#define CALCULATE_BER(avg_errors, count) \
+       ((u32)(avg_errors * 4)/(count*64*188*8))
+#define CALCULATE_SNR(data) \
+       ((u32)((10 * (u32)data / 64) - 2.5))
+#else
+#define CALCULATE_BER(avg_errors, count) 0
+#define CALCULATE_SNR(data) 0
+#endif
+
+static int mxl111sf_demod_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       u8 val1, val2, val3;
+       int ret;
+
+       *ber = 0;
+
+       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_LSB_REG, &val1);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_MSB_REG, &val2);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_demod_read_reg(state, V6_N_ACCUMULATE_REG, &val3);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *ber = CALCULATE_BER((val1 | (val2 << 8)), val3);
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_calc_snr(struct mxl111sf_demod_state *state,
+                                  u16 *snr)
+{
+       u8 val1, val2;
+       int ret;
+
+       *snr = 0;
+
+       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_LSB_REG, &val1);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_MSB_REG, &val2);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *snr = CALCULATE_SNR(val1 | ((val2 & 0x03) << 8));
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+
+       int ret = mxl111sf_demod_calc_snr(state, snr);
+       if (mxl_fail(ret))
+               goto fail;
+
+       *snr /= 10; /* 0.1 dB */
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_read_status(struct dvb_frontend *fe,
+                                     fe_status_t *status)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       int ret, locked, cr_lock, sync_lock, fec_lock;
+
+       *status = 0;
+
+       ret = mxl1x1sf_demod_get_rs_lock_status(state, &locked);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_demod_get_tps_lock_status(state, &cr_lock);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_demod_get_sync_lock_status(state, &sync_lock);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_demod_get_fec_lock_status(state, &fec_lock);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if (locked)
+               *status |= FE_HAS_SIGNAL;
+       if (cr_lock)
+               *status |= FE_HAS_CARRIER;
+       if (sync_lock)
+               *status |= FE_HAS_SYNC;
+       if (fec_lock) /* false positives? */
+               *status |= FE_HAS_VITERBI;
+
+       if ((locked) && (cr_lock) && (sync_lock))
+               *status |= FE_HAS_LOCK;
+fail:
+       return ret;
+}
+
+static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
+                                              u16 *signal_strength)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       fe_modulation_t constellation;
+       u16 snr;
+
+       mxl111sf_demod_calc_snr(state, &snr);
+       mxl1x1sf_demod_get_tps_constellation(state, &constellation);
+
+       switch (constellation) {
+       case QPSK:
+               *signal_strength = (snr >= 1300) ?
+                       min(65535, snr * 44) : snr * 38;
+               break;
+       case QAM_16:
+               *signal_strength = (snr >= 1500) ?
+                       min(65535, snr * 38) : snr * 33;
+               break;
+       case QAM_64:
+               *signal_strength = (snr >= 2000) ?
+                       min(65535, snr * 29) : snr * 25;
+               break;
+       default:
+               *signal_strength = 0;
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe,
+                                      struct dvb_frontend_parameters *p)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+
+       mxl_dbg("()");
+#if 0
+       p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF;
+#endif
+       if (fe->ops.tuner_ops.get_bandwidth)
+               fe->ops.tuner_ops.get_bandwidth(fe, &p->u.ofdm.bandwidth);
+       if (fe->ops.tuner_ops.get_frequency)
+               fe->ops.tuner_ops.get_frequency(fe, &p->frequency);
+       mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_HP);
+       mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_LP);
+       mxl1x1sf_demod_get_tps_constellation(state, &p->u.ofdm.constellation);
+       mxl1x1sf_demod_get_tps_guard_fft_mode(state,
+                                             &p->u.ofdm.transmission_mode);
+       mxl1x1sf_demod_get_tps_guard_interval(state,
+                                             &p->u.ofdm.guard_interval);
+       mxl1x1sf_demod_get_tps_hierarchy(state,
+                                        &p->u.ofdm.hierarchy_information);
+
+       return 0;
+}
+
+static
+int mxl111sf_demod_get_tune_settings(struct dvb_frontend *fe,
+                                    struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void mxl111sf_demod_release(struct dvb_frontend *fe)
+{
+       struct mxl111sf_demod_state *state = fe->demodulator_priv;
+       mxl_dbg("()");
+       kfree(state);
+       fe->demodulator_priv = NULL;
+}
+
+static struct dvb_frontend_ops mxl111sf_demod_ops = {
+
+       .info = {
+               .name               = "MaxLinear MxL111SF DVB-T demodulator",
+               .type               = FE_OFDM,
+               .frequency_min      = 177000000,
+               .frequency_max      = 858000000,
+               .frequency_stepsize = 166666,
+               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+                       FE_CAN_QAM_AUTO |
+                       FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+                       FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
+       },
+       .release              = mxl111sf_demod_release,
+#if 0
+       .init                 = mxl111sf_init,
+       .i2c_gate_ctrl        = mxl111sf_i2c_gate_ctrl,
+#endif
+       .set_frontend         = mxl111sf_demod_set_frontend,
+       .get_frontend         = mxl111sf_demod_get_frontend,
+       .get_tune_settings    = mxl111sf_demod_get_tune_settings,
+       .read_status          = mxl111sf_demod_read_status,
+       .read_signal_strength = mxl111sf_demod_read_signal_strength,
+       .read_ber             = mxl111sf_demod_read_ber,
+       .read_snr             = mxl111sf_demod_read_snr,
+       .read_ucblocks        = mxl111sf_demod_read_ucblocks,
+};
+
+struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_demod_config *cfg)
+{
+       struct mxl111sf_demod_state *state = NULL;
+
+       mxl_dbg("()");
+
+       state = kzalloc(sizeof(struct mxl111sf_demod_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       state->mxl_state = mxl_state;
+       state->cfg = cfg;
+
+       memcpy(&state->fe.ops, &mxl111sf_demod_ops,
+              sizeof(struct dvb_frontend_ops));
+
+       state->fe.demodulator_priv = state;
+       return &state->fe;
+}
+EXPORT_SYMBOL_GPL(mxl111sf_demod_attach);
+
+MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.h b/drivers/media/dvb/dvb-usb/mxl111sf-demod.h
new file mode 100644 (file)
index 0000000..432706a
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator
+ *
+ *  Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MXL111SF_DEMOD_H__
+#define __MXL111SF_DEMOD_H__
+
+#include "dvb_frontend.h"
+#include "mxl111sf.h"
+
+struct mxl111sf_demod_config {
+       int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
+       int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
+       int (*program_regs)(struct mxl111sf_state *state,
+                           struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
+};
+
+#if defined(CONFIG_DVB_USB_MXL111SF) || \
+       (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
+extern
+struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_demod_config *cfg);
+#else
+static inline
+struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
+                                          struct mxl111sf_demod_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_USB_MXL111SF */
+
+#endif /* __MXL111SF_DEMOD_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
index 546ba59..b5c98da 100644 (file)
@@ -17,6 +17,7 @@
 #include "mxl111sf-i2c.h"
 #include "mxl111sf-gpio.h"
 
+#include "mxl111sf-demod.h"
 #include "mxl111sf-tuner.h"
 
 #include "lgdt3305.h"
@@ -362,6 +363,22 @@ static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
        return ret;
 }
 
+static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+       struct dvb_usb_device *d = adap->dev;
+       struct mxl111sf_state *state = d->priv;
+       int ret = 0;
+
+       deb_info("%s(%d)\n", __func__, onoff);
+
+       if (onoff) {
+               ret = mxl111sf_enable_usb_output(state);
+               mxl_fail(ret);
+       }
+
+       return ret;
+}
+
 /* ------------------------------------------------------------------------ */
 
 static struct lgdt3305_config hauppauge_lgdt3305_config = {
@@ -438,6 +455,70 @@ fail:
        return ret;
 }
 
+static struct mxl111sf_demod_config mxl_demod_config = {
+       .read_reg        = mxl111sf_read_reg,
+       .write_reg       = mxl111sf_write_reg,
+       .program_regs    = mxl111sf_ctrl_program_regs,
+};
+
+static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap)
+{
+       struct dvb_usb_device *d = adap->dev;
+       struct mxl111sf_state *state = d->priv;
+       int fe_id = adap->num_frontends_initialized;
+       struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
+       int ret;
+
+       deb_adv("%s()\n", __func__);
+
+       /* save a pointer to the dvb_usb_device in device state */
+       state->d = d;
+       adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
+       state->alt_mode = adap_state->alt_mode;
+
+       if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
+               err("set interface failed");
+
+       state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
+       adap_state->gpio_mode = state->gpio_mode;
+       adap_state->device_mode = MXL_SOC_MODE;
+       adap_state->ep6_clockphase = 1;
+
+       ret = mxl1x1sf_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl111sf_init_tuner_demod(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl111sf_enable_usb_output(state);
+       if (mxl_fail(ret))
+               goto fail;
+       ret = mxl1x1sf_top_master_ctrl(state, 1);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* dont care if this fails */
+       mxl111sf_init_port_expander(state);
+
+       adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state,
+                             &mxl_demod_config);
+       if (adap->fe_adap[fe_id].fe) {
+               adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
+               adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
+               adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
+               adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
+               return 0;
+       }
+       ret = -EIO;
+fail:
+       return ret;
+}
+
 static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
                                        int antpath)
 {
@@ -567,7 +648,8 @@ struct i2c_algorithm mxl111sf_i2c_algo = {
 #endif
 };
 
-/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
+static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
 static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
 static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
 
@@ -580,8 +662,14 @@ static int mxl111sf_probe(struct usb_interface *intf,
 
        if (((dvb_usb_mxl111sf_isoc) &&
             (0 == dvb_usb_device_init(intf,
+                                      &mxl111sf_dvbt_isoc_properties,
+                                      THIS_MODULE, &d, adapter_nr) ||
+             0 == dvb_usb_device_init(intf,
                                       &mxl111sf_atsc_isoc_properties,
                                       THIS_MODULE, &d, adapter_nr))) ||
+           0 == dvb_usb_device_init(intf,
+                                    &mxl111sf_dvbt_bulk_properties,
+                                    THIS_MODULE, &d, adapter_nr) ||
            0 == dvb_usb_device_init(intf,
                                     &mxl111sf_atsc_bulk_properties,
                                     THIS_MODULE, &d, adapter_nr) || 0) {
@@ -669,6 +757,36 @@ static struct usb_device_id mxl111sf_table[] = {
 MODULE_DEVICE_TABLE(usb, mxl111sf_table);
 
 
+#define MXL111SF_EP4_BULK_STREAMING_CONFIG             \
+       .streaming_ctrl = mxl111sf_ep4_streaming_ctrl,  \
+       .stream = {                                     \
+               .type = USB_BULK,                       \
+               .count = 5,                             \
+               .endpoint = 0x04,                       \
+               .u = {                                  \
+                       .bulk = {                       \
+                               .buffersize = 8192,     \
+                       }                               \
+               }                                       \
+       }
+
+/* FIXME: works for v6 but not v8 silicon */
+#define MXL111SF_EP4_ISOC_STREAMING_CONFIG             \
+       .streaming_ctrl = mxl111sf_ep4_streaming_ctrl,  \
+       .stream = {                                     \
+               .type = USB_ISOC,                       \
+               .count = 5,                             \
+               .endpoint = 0x04,                       \
+               .u = {                                  \
+                       .isoc = {                       \
+                               .framesperurb = 96,     \
+                               /* FIXME: v6 SILICON: */        \
+                               .framesize = 564,       \
+                               .interval = 1,          \
+                       }                               \
+               }                                       \
+       }
+
 #define MXL111SF_EP6_BULK_STREAMING_CONFIG             \
        .streaming_ctrl = mxl111sf_ep6_streaming_ctrl,  \
        .stream = {                                     \
@@ -712,7 +830,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table);
        .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
        .size_of_priv     = sizeof(struct mxl111sf_state)
 
-static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
+static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
        MXL111SF_DEFAULT_DEVICE_PROPERTIES,
 
        .num_adapters = 1,
@@ -723,10 +841,106 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
                .fe = {{
                        .size_of_priv     = sizeof(struct mxl111sf_adap_state),
 
+                       .frontend_attach  = mxl111sf_attach_demod,
+                       .tuner_attach     = mxl111sf_attach_tuner,
+
+                       MXL111SF_EP4_BULK_STREAMING_CONFIG,
+               } },
+               },
+       },
+       .num_device_descs = 4,
+       .devices = {
+               {   "Hauppauge 126xxx DVBT (bulk)",
+                       { NULL },
+                       { &mxl111sf_table[4], &mxl111sf_table[8],
+                         NULL },
+               },
+               {   "Hauppauge 117xxx DVBT (bulk)",
+                       { NULL },
+                       { &mxl111sf_table[15], &mxl111sf_table[18],
+                         NULL },
+               },
+               {   "Hauppauge 138xxx DVBT (bulk)",
+                       { NULL },
+                       { &mxl111sf_table[20], &mxl111sf_table[22],
+                         &mxl111sf_table[24], &mxl111sf_table[26],
+                         NULL },
+               },
+               {   "Hauppauge 126xxx (tp-bulk)",
+                       { NULL },
+                       { &mxl111sf_table[28], &mxl111sf_table[30],
+                         NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
+       MXL111SF_DEFAULT_DEVICE_PROPERTIES,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .fe_ioctl_override = mxl111sf_fe_ioctl_override,
+               .num_frontends = 1,
+               .fe = {{
+                       .size_of_priv     = sizeof(struct mxl111sf_adap_state),
+
+                       .frontend_attach  = mxl111sf_attach_demod,
+                       .tuner_attach     = mxl111sf_attach_tuner,
+
+                       MXL111SF_EP4_ISOC_STREAMING_CONFIG,
+               } },
+               },
+       },
+       .num_device_descs = 4,
+       .devices = {
+               {   "Hauppauge 126xxx DVBT (isoc)",
+                       { NULL },
+                       { &mxl111sf_table[4], &mxl111sf_table[8],
+                         NULL },
+               },
+               {   "Hauppauge 117xxx DVBT (isoc)",
+                       { NULL },
+                       { &mxl111sf_table[15], &mxl111sf_table[18],
+                         NULL },
+               },
+               {   "Hauppauge 138xxx DVBT (isoc)",
+                       { NULL },
+                       { &mxl111sf_table[20], &mxl111sf_table[22],
+                         &mxl111sf_table[24], &mxl111sf_table[26],
+                         NULL },
+               },
+               {   "Hauppauge 126xxx (tp-isoc)",
+                       { NULL },
+                       { &mxl111sf_table[28], &mxl111sf_table[30],
+                         NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
+       MXL111SF_DEFAULT_DEVICE_PROPERTIES,
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+               .fe_ioctl_override = mxl111sf_fe_ioctl_override,
+               .num_frontends = 2,
+               .fe = {{
+                       .size_of_priv     = sizeof(struct mxl111sf_adap_state),
+
                        .frontend_attach  = mxl111sf_lgdt3305_frontend_attach,
                        .tuner_attach     = mxl111sf_attach_tuner,
 
                        MXL111SF_EP6_BULK_STREAMING_CONFIG,
+               },
+               {
+                       .size_of_priv     = sizeof(struct mxl111sf_adap_state),
+
+                       .frontend_attach  = mxl111sf_attach_demod,
+                       .tuner_attach     = mxl111sf_attach_tuner,
+
+                       MXL111SF_EP4_BULK_STREAMING_CONFIG,
                }},
                },
        },
@@ -776,7 +990,7 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
        .adapter = {
                {
                .fe_ioctl_override = mxl111sf_fe_ioctl_override,
-               .num_frontends = 1,
+               .num_frontends = 2,
                .fe = {{
                        .size_of_priv     = sizeof(struct mxl111sf_adap_state),
 
@@ -784,6 +998,14 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
                        .tuner_attach     = mxl111sf_attach_tuner,
 
                        MXL111SF_EP6_ISOC_STREAMING_CONFIG,
+               },
+               {
+                       .size_of_priv     = sizeof(struct mxl111sf_adap_state),
+
+                       .frontend_attach  = mxl111sf_attach_demod,
+                       .tuner_attach     = mxl111sf_attach_tuner,
+
+                       MXL111SF_EP4_ISOC_STREAMING_CONFIG,
                }},
                },
        },
index 5a2c7bb..364d89f 100644 (file)
@@ -133,7 +133,7 @@ extern int dvb_usb_mxl111sf_debug;
 /* The following allows the mxl_fail() macro defined below to work
  * in externel modules, such as mxl111sf-tuner.ko, even though
  * dvb_usb_mxl111sf_debug is not defined within those modules */
-#ifdef __MXL111SF_TUNER_H__
+#if (defined(__MXL111SF_TUNER_H__)) || (defined(__MXL111SF_DEMOD_H__))
 #define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG
 #else
 #define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug
index 8987361..13ebeff 100644 (file)
@@ -11,4 +11,4 @@ ccflags-y += -Idrivers/media/dvb/frontends/
 ccflags-y += -Idrivers/media/common/tuners/
 
 # For the staging CI driver cxd2099
-ccflags-y += -Idrivers/staging/cxd2099/
+ccflags-y += -Idrivers/staging/media/cxd2099/
index 95ddcc4..db20904 100644 (file)
@@ -128,8 +128,10 @@ struct tea5764_write_regs {
        u16 rdsbbl;                             /* PAUSEDET & RDSBBL */
 } __attribute__ ((packed));
 
-#ifndef RADIO_TEA5764_XTAL
+#ifdef CONFIG_RADIO_TEA5764_XTAL
 #define RADIO_TEA5764_XTAL 1
+#else
+#define RADIO_TEA5764_XTAL 0
 #endif
 
 static int radio_nr = -1;
index d285c8c..b303a3f 100644 (file)
@@ -517,6 +517,13 @@ config VIDEO_NOON010PC30
 
 source "drivers/media/video/m5mols/Kconfig"
 
+config VIDEO_S5K6AA
+       tristate "Samsung S5K6AAFX sensor support"
+       depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       ---help---
+         This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
+         camera sensor with an embedded SoC image signal processor.
+
 comment "Flash devices"
 
 config VIDEO_ADP1653
@@ -736,6 +743,8 @@ source "drivers/media/video/cx88/Kconfig"
 
 source "drivers/media/video/cx23885/Kconfig"
 
+source "drivers/media/video/cx25821/Kconfig"
+
 source "drivers/media/video/au0828/Kconfig"
 
 source "drivers/media/video/ivtv/Kconfig"
index 11fff97..117f9c4 100644 (file)
@@ -72,6 +72,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
 obj-$(CONFIG_VIDEO_SR030PC30)  += sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)        += noon010pc30.o
 obj-$(CONFIG_VIDEO_M5MOLS)     += m5mols/
+obj-$(CONFIG_VIDEO_S5K6AA)     += s5k6aa.o
 obj-$(CONFIG_VIDEO_ADP1653)    += adp1653.o
 
 obj-$(CONFIG_SOC_CAMERA_IMX074)                += imx074.o
@@ -104,6 +105,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
 obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
 obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
+obj-$(CONFIG_VIDEO_CX25821) += cx25821/
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
 obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
 obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
index 774715d..8c775c5 100644 (file)
@@ -94,6 +94,7 @@ struct atmel_isi {
        unsigned int                    irq;
 
        struct isi_platform_data        *pdata;
+       u16                             width_flags;    /* max 12 bits */
 
        struct list_head                video_buffer_list;
        struct frame_buffer             *active;
@@ -248,9 +249,9 @@ static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
 /* ------------------------------------------------------------------
        Videobuf operations
    ------------------------------------------------------------------*/
-static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-                               unsigned int *nplanes, unsigned int sizes[],
-                               void *alloc_ctxs[])
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+                               unsigned int *nbuffers, unsigned int *nplanes,
+                               unsigned int sizes[], void *alloc_ctxs[])
 {
        struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
@@ -647,50 +648,42 @@ static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
                 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
 }
 
-static unsigned long make_bus_param(struct atmel_isi *isi)
-{
-       unsigned long flags;
-       /*
-        * Platform specified synchronization and pixel clock polarities are
-        * only a recommendation and are only used during probing. Atmel ISI
-        * camera interface only works in master mode, i.e., uses HSYNC and
-        * VSYNC signals from the sensor
-        */
-       flags = SOCAM_MASTER |
-               SOCAM_HSYNC_ACTIVE_HIGH |
-               SOCAM_HSYNC_ACTIVE_LOW |
-               SOCAM_VSYNC_ACTIVE_HIGH |
-               SOCAM_VSYNC_ACTIVE_LOW |
-               SOCAM_PCLK_SAMPLE_RISING |
-               SOCAM_PCLK_SAMPLE_FALLING |
-               SOCAM_DATA_ACTIVE_HIGH;
-
-       if (isi->pdata->data_width_flags & ISI_DATAWIDTH_10)
-               flags |= SOCAM_DATAWIDTH_10;
-
-       if (isi->pdata->data_width_flags & ISI_DATAWIDTH_8)
-               flags |= SOCAM_DATAWIDTH_8;
-
-       if (flags & SOCAM_DATAWIDTH_MASK)
-               return flags;
-
-       return 0;
-}
+#define ISI_BUS_PARAM (V4L2_MBUS_MASTER |      \
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH |   \
+               V4L2_MBUS_HSYNC_ACTIVE_LOW |    \
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH |   \
+               V4L2_MBUS_VSYNC_ACTIVE_LOW |    \
+               V4L2_MBUS_PCLK_SAMPLE_RISING |  \
+               V4L2_MBUS_PCLK_SAMPLE_FALLING | \
+               V4L2_MBUS_DATA_ACTIVE_HIGH)
 
 static int isi_camera_try_bus_param(struct soc_camera_device *icd,
                                    unsigned char buswidth)
 {
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct atmel_isi *isi = ici->priv;
-       unsigned long camera_flags;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long common_flags;
        int ret;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-       ret = soc_camera_bus_param_compatible(camera_flags,
-                                       make_bus_param(isi));
-       if (!ret)
-               return -EINVAL;
-       return 0;
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg,
+                                                         ISI_BUS_PARAM);
+               if (!common_flags) {
+                       dev_warn(icd->parent,
+                                "Flags incompatible: camera 0x%x, host 0x%x\n",
+                                cfg.flags, ISI_BUS_PARAM);
+                       return -EINVAL;
+               }
+       } else if (ret != -ENOIOCTLCMD) {
+               return ret;
+       }
+
+       if ((1 << (buswidth - 1)) & isi->width_flags)
+               return 0;
+       return -EINVAL;
 }
 
 
@@ -812,59 +805,71 @@ static int isi_camera_querycap(struct soc_camera_host *ici,
 
 static int isi_camera_set_bus_param(struct soc_camera_device *icd, u32 pixfmt)
 {
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct atmel_isi *isi = ici->priv;
-       unsigned long bus_flags, camera_flags, common_flags;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long common_flags;
        int ret;
        u32 cfg1 = 0;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-
-       bus_flags = make_bus_param(isi);
-       common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
-       dev_dbg(icd->parent, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n",
-               camera_flags, bus_flags, common_flags);
-       if (!common_flags)
-               return -EINVAL;
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg,
+                                                         ISI_BUS_PARAM);
+               if (!common_flags) {
+                       dev_warn(icd->parent,
+                                "Flags incompatible: camera 0x%x, host 0x%x\n",
+                                cfg.flags, ISI_BUS_PARAM);
+                       return -EINVAL;
+               }
+       } else if (ret != -ENOIOCTLCMD) {
+               return ret;
+       } else {
+               common_flags = ISI_BUS_PARAM;
+       }
+       dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n",
+               cfg.flags, ISI_BUS_PARAM, common_flags);
 
        /* Make choises, based on platform preferences */
-       if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
                if (isi->pdata->hsync_act_low)
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
                else
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
        }
 
-       if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
                if (isi->pdata->vsync_act_low)
-                       common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
                else
-                       common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
        }
 
-       if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
-           (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+       if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
+           (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
                if (isi->pdata->pclk_act_falling)
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
                else
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
        }
 
-       ret = icd->ops->set_bus_param(icd, common_flags);
-       if (ret < 0) {
-               dev_dbg(icd->parent, "Camera set_bus_param(%lx) returned %d\n",
+       cfg.flags = common_flags;
+       ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
+       if (ret < 0 && ret != -ENOIOCTLCMD) {
+               dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
                        common_flags, ret);
                return ret;
        }
 
        /* set bus param for ISI */
-       if (common_flags & SOCAM_HSYNC_ACTIVE_LOW)
+       if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
                cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
-       if (common_flags & SOCAM_VSYNC_ACTIVE_LOW)
+       if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
                cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
-       if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
+       if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
                cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
 
        if (isi->pdata->has_emb_sync)
@@ -983,6 +988,11 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev)
                goto err_ioremap;
        }
 
+       if (pdata->data_width_flags & ISI_DATAWIDTH_8)
+               isi->width_flags = 1 << 7;
+       if (pdata->data_width_flags & ISI_DATAWIDTH_10)
+               isi->width_flags |= 1 << 9;
+
        isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
 
        irq = platform_get_irq(pdev, 0);
index 9e2f870..c6ff32a 100644 (file)
@@ -1085,6 +1085,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
                setup.addr = ADDR_UNSET;
                setup.type = cx->options.tuner;
                setup.mode_mask = T_ANALOG_TV;  /* matches TV tuners */
+               if (cx->options.radio > 0)
+                       setup.mode_mask |= T_RADIO;
                setup.tuner_callback = (setup.type == TUNER_XC2028) ?
                        cx18_reset_tuner_gpio : NULL;
                cx18_call_all(cx, tuner, s_type_addr, &setup);
similarity index 99%
rename from drivers/staging/cx25821/cx25821-video.c
rename to drivers/media/video/cx25821/cx25821-video.c
index 084fc08..4d6907c 100644 (file)
@@ -1312,7 +1312,7 @@ int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
                        return err;
        }
 
-       if (i > 2) {
+       if (i >= CX25821_NR_INPUT) {
                dprintk(1, "%s(): -EINVAL\n", __func__);
                return -EINVAL;
        }
similarity index 99%
rename from drivers/staging/cx25821/cx25821.h
rename to drivers/media/video/cx25821/cx25821.h
index db2615b..2d2d009 100644 (file)
@@ -98,6 +98,7 @@
 #define CX25821_BOARD_CONEXANT_ATHENA10 1
 #define MAX_VID_CHANNEL_NUM     12
 #define VID_CHANNEL_NUM 8
+#define CX25821_NR_INPUT 2
 
 struct cx25821_fmt {
        char *name;
@@ -196,7 +197,7 @@ struct cx25821_board {
        unsigned char radio_addr;
 
        u32 clk_freq;
-       struct cx25821_input input[2];
+       struct cx25821_input input[CX25821_NR_INPUT];
 };
 
 struct cx25821_subid {
index 4240f0b..9b747c2 100644 (file)
@@ -1923,6 +1923,8 @@ struct usb_device_id em28xx_id_table[] = {
                        .driver_info = EM2860_BOARD_TERRATEC_AV350 },
        { USB_DEVICE(0x0ccd, 0x0096),
                        .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
+       { USB_DEVICE(0x0ccd, 0x10AF),
+                       .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
        { USB_DEVICE(0x0fd9, 0x0033),
                        .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE},
        { USB_DEVICE(0x185b, 0x2870),
index 0382ea7..8775e26 100644 (file)
 
 #include <linux/delay.h>
 #include <linux/i2c.h>
+#include <linux/v4l2-mediabus.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 
 #include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-chip-ident.h>
 
@@ -267,6 +267,17 @@ static int imx074_g_chip_ident(struct v4l2_subdev *sd,
        return 0;
 }
 
+static int imx074_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       cfg->type = V4L2_MBUS_CSI2;
+       cfg->flags = V4L2_MBUS_CSI2_2_LANE |
+               V4L2_MBUS_CSI2_CHANNEL_0 |
+               V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+       return 0;
+}
+
 static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
        .s_stream       = imx074_s_stream,
        .s_mbus_fmt     = imx074_s_fmt,
@@ -275,6 +286,7 @@ static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
        .enum_mbus_fmt  = imx074_enum_fmt,
        .g_crop         = imx074_g_crop,
        .cropcap        = imx074_cropcap,
+       .g_mbus_config  = imx074_g_mbus_config,
 };
 
 static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
@@ -286,28 +298,7 @@ static struct v4l2_subdev_ops imx074_subdev_ops = {
        .video  = &imx074_subdev_video_ops,
 };
 
-/*
- * We have to provide soc-camera operations, but we don't have anything to say
- * there. The MIPI CSI2 driver will provide .query_bus_param and .set_bus_param
- */
-static unsigned long imx074_query_bus_param(struct soc_camera_device *icd)
-{
-       return 0;
-}
-
-static int imx074_set_bus_param(struct soc_camera_device *icd,
-                                unsigned long flags)
-{
-       return -EINVAL;
-}
-
-static struct soc_camera_ops imx074_ops = {
-       .query_bus_param        = imx074_query_bus_param,
-       .set_bus_param          = imx074_set_bus_param,
-};
-
-static int imx074_video_probe(struct soc_camera_device *icd,
-                             struct i2c_client *client)
+static int imx074_video_probe(struct i2c_client *client)
 {
        int ret;
        u16 id;
@@ -417,17 +408,10 @@ static int imx074_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 {
        struct imx074 *priv;
-       struct soc_camera_device *icd = client->dev.platform_data;
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-       struct soc_camera_link *icl;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "IMX074: missing soc-camera data!\n");
-               return -EINVAL;
-       }
-
-       icl = to_soc_camera_link(icd);
        if (!icl) {
                dev_err(&client->dev, "IMX074: missing platform data!\n");
                return -EINVAL;
@@ -445,12 +429,10 @@ static int imx074_probe(struct i2c_client *client,
 
        v4l2_i2c_subdev_init(&priv->subdev, client, &imx074_subdev_ops);
 
-       icd->ops        = &imx074_ops;
        priv->fmt       = &imx074_colour_fmts[0];
 
-       ret = imx074_video_probe(icd, client);
+       ret = imx074_video_probe(client);
        if (ret < 0) {
-               icd->ops = NULL;
                kfree(priv);
                return ret;
        }
@@ -461,10 +443,8 @@ static int imx074_probe(struct i2c_client *client,
 static int imx074_remove(struct i2c_client *client)
 {
        struct imx074 *priv = to_imx074(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
 
-       icd->ops = NULL;
        if (icl->free_bus)
                icl->free_bus(icl);
        kfree(priv);
index 0fb7552..41108a9 100644 (file)
@@ -1180,6 +1180,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
                setup.addr = ADDR_UNSET;
                setup.type = itv->options.tuner;
                setup.mode_mask = T_ANALOG_TV;  /* matches TV tuners */
+               if (itv->options.radio > 0)
+                       setup.mode_mask |= T_RADIO;
                setup.tuner_callback = (setup.type == TUNER_XC2028) ?
                        ivtv_reset_tuner_gpio : NULL;
                ivtv_call_all(itv, tuner, s_type_addr, &setup);
index 1141b97..80ec64d 100644 (file)
@@ -883,7 +883,8 @@ static int mcam_read_setup(struct mcam_camera *cam)
  * Videobuf2 interface code.
  */
 
-static int mcam_vb_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
+static int mcam_vb_queue_setup(struct vb2_queue *vq,
+               const struct v4l2_format *fmt, unsigned int *nbufs,
                unsigned int *num_planes, unsigned int sizes[],
                void *alloc_ctxs[])
 {
index 9594b52..12897e8 100644 (file)
@@ -738,9 +738,10 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
  * Queue operations
  */
 
-static int m2mtest_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-                               unsigned int *nplanes, unsigned int sizes[],
-                               void *alloc_ctxs[])
+static int m2mtest_queue_setup(struct vb2_queue *vq,
+                               const struct v4l2_format *fmt,
+                               unsigned int *nbuffers, unsigned int *nplanes,
+                               unsigned int sizes[], void *alloc_ctxs[])
 {
        struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq);
        struct m2mtest_q_data *q_data;
index 4da9cca..63ae5c6 100644 (file)
 #include <linux/i2c.h>
 #include <linux/log2.h>
 
+#include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
+#include <media/v4l2-ctrls.h>
 
 /*
  * mt9m001 i2c address 0x5d
@@ -84,15 +86,19 @@ static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
 
 struct mt9m001 {
        struct v4l2_subdev subdev;
+       struct v4l2_ctrl_handler hdl;
+       struct {
+               /* exposure/auto-exposure cluster */
+               struct v4l2_ctrl *autoexposure;
+               struct v4l2_ctrl *exposure;
+       };
        struct v4l2_rect rect;  /* Sensor window */
        const struct mt9m001_datafmt *fmt;
        const struct mt9m001_datafmt *fmts;
        int num_fmts;
        int model;      /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
-       unsigned int gain;
-       unsigned int exposure;
+       unsigned int total_h;
        unsigned short y_skip_top;      /* Lines to skip at the top */
-       unsigned char autoexposure;
 };
 
 static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
@@ -165,54 +171,13 @@ static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
        return 0;
 }
 
-static int mt9m001_set_bus_param(struct soc_camera_device *icd,
-                                unsigned long flags)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
-
-       /* Only one width bit may be set */
-       if (!is_power_of_2(width_flag))
-               return -EINVAL;
-
-       if (icl->set_bus_param)
-               return icl->set_bus_param(icl, width_flag);
-
-       /*
-        * Without board specific bus width settings we only support the
-        * sensors native bus width
-        */
-       if (width_flag == SOCAM_DATAWIDTH_10)
-               return 0;
-
-       return -EINVAL;
-}
-
-static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       /* MT9M001 has all capture_format parameters fixed */
-       unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
-               SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
-               SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER;
-
-       if (icl->query_bus_param)
-               flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
-       else
-               flags |= SOCAM_DATAWIDTH_10;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
 static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct mt9m001 *mt9m001 = to_mt9m001(client);
        struct v4l2_rect rect = a->c;
-       struct soc_camera_device *icd = client->dev.platform_data;
        int ret;
        const u16 hblank = 9, vblank = 25;
-       unsigned int total_h;
 
        if (mt9m001->fmts == mt9m001_colour_fmts)
                /*
@@ -231,7 +196,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
        soc_camera_limit_side(&rect.top, &rect.height,
                     MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
 
-       total_h = rect.height + mt9m001->y_skip_top + vblank;
+       mt9m001->total_h = rect.height + mt9m001->y_skip_top + vblank;
 
        /* Blanking and start values - default... */
        ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
@@ -240,7 +205,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 
        /*
         * The caller provides a supported format, as verified per
-        * call to icd->try_fmt()
+        * call to .try_mbus_fmt()
         */
        if (!ret)
                ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
@@ -251,17 +216,8 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
        if (!ret)
                ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
                                rect.height + mt9m001->y_skip_top - 1);
-       if (!ret && mt9m001->autoexposure) {
-               ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h);
-               if (!ret) {
-                       const struct v4l2_queryctrl *qctrl =
-                               soc_camera_find_qctrl(icd->ops,
-                                                     V4L2_CID_EXPOSURE);
-                       mt9m001->exposure = (524 + (total_h - 1) *
-                                (qctrl->maximum - qctrl->minimum)) /
-                               1048 + qctrl->minimum;
-               }
-       }
+       if (!ret && v4l2_ctrl_g_ctrl(mt9m001->autoexposure) == V4L2_EXPOSURE_AUTO)
+               ret = reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h);
 
        if (!ret)
                mt9m001->rect = rect;
@@ -421,107 +377,48 @@ static int mt9m001_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
-static const struct v4l2_queryctrl mt9m001_controls[] = {
-       {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Vertically",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       }, {
-               .id             = V4L2_CID_GAIN,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Gain",
-               .minimum        = 0,
-               .maximum        = 127,
-               .step           = 1,
-               .default_value  = 64,
-               .flags          = V4L2_CTRL_FLAG_SLIDER,
-       }, {
-               .id             = V4L2_CID_EXPOSURE,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Exposure",
-               .minimum        = 1,
-               .maximum        = 255,
-               .step           = 1,
-               .default_value  = 255,
-               .flags          = V4L2_CTRL_FLAG_SLIDER,
-       }, {
-               .id             = V4L2_CID_EXPOSURE_AUTO,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Automatic Exposure",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 1,
-       }
-};
-
-static struct soc_camera_ops mt9m001_ops = {
-       .set_bus_param          = mt9m001_set_bus_param,
-       .query_bus_param        = mt9m001_query_bus_param,
-       .controls               = mt9m001_controls,
-       .num_controls           = ARRAY_SIZE(mt9m001_controls),
-};
-
-static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-       int data;
+       struct mt9m001 *mt9m001 = container_of(ctrl->handler,
+                                              struct mt9m001, hdl);
+       s32 min, max;
 
        switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               data = reg_read(client, MT9M001_READ_OPTIONS2);
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !!(data & 0x8000);
-               break;
        case V4L2_CID_EXPOSURE_AUTO:
-               ctrl->value = mt9m001->autoexposure;
-               break;
-       case V4L2_CID_GAIN:
-               ctrl->value = mt9m001->gain;
-               break;
-       case V4L2_CID_EXPOSURE:
-               ctrl->value = mt9m001->exposure;
+               min = mt9m001->exposure->minimum;
+               max = mt9m001->exposure->maximum;
+               mt9m001->exposure->val =
+                       (524 + (mt9m001->total_h - 1) * (max - min)) / 1048 + min;
                break;
        }
        return 0;
 }
 
-static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+       struct mt9m001 *mt9m001 = container_of(ctrl->handler,
+                                              struct mt9m001, hdl);
+       struct v4l2_subdev *sd = &mt9m001->subdev;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m001 *mt9m001 = to_mt9m001(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
-       const struct v4l2_queryctrl *qctrl;
+       struct v4l2_ctrl *exp = mt9m001->exposure;
        int data;
 
-       qctrl = soc_camera_find_qctrl(&mt9m001_ops, ctrl->id);
-
-       if (!qctrl)
-               return -EINVAL;
-
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               if (ctrl->value)
+               if (ctrl->val)
                        data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
                else
                        data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
                if (data < 0)
                        return -EIO;
-               break;
+               return 0;
+
        case V4L2_CID_GAIN:
-               if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
-                       return -EINVAL;
                /* See Datasheet Table 7, Gain settings. */
-               if (ctrl->value <= qctrl->default_value) {
+               if (ctrl->val <= ctrl->default_value) {
                        /* Pack it into 0..1 step 0.125, register values 0..8 */
-                       unsigned long range = qctrl->default_value - qctrl->minimum;
-                       data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
+                       unsigned long range = ctrl->default_value - ctrl->minimum;
+                       data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
 
                        dev_dbg(&client->dev, "Setting gain %d\n", data);
                        data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
@@ -530,8 +427,8 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
                } else {
                        /* Pack it into 1.125..15 variable step, register values 9..67 */
                        /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
-                       unsigned long range = qctrl->maximum - qctrl->default_value - 1;
-                       unsigned long gain = ((ctrl->value - qctrl->default_value - 1) *
+                       unsigned long range = ctrl->maximum - ctrl->default_value - 1;
+                       unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
                                               111 + range / 2) / range + 9;
 
                        if (gain <= 32)
@@ -547,66 +444,44 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
                        if (data < 0)
                                return -EIO;
                }
+               return 0;
 
-               /* Success */
-               mt9m001->gain = ctrl->value;
-               break;
-       case V4L2_CID_EXPOSURE:
-               /* mt9m001 has maximum == default */
-               if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
-                       return -EINVAL;
-               else {
-                       unsigned long range = qctrl->maximum - qctrl->minimum;
-                       unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 +
+       case V4L2_CID_EXPOSURE_AUTO:
+               if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
+                       unsigned long range = exp->maximum - exp->minimum;
+                       unsigned long shutter = ((exp->val - exp->minimum) * 1048 +
                                                 range / 2) / range + 1;
 
                        dev_dbg(&client->dev,
                                "Setting shutter width from %d to %lu\n",
-                               reg_read(client, MT9M001_SHUTTER_WIDTH),
-                               shutter);
+                               reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
                        if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
                                return -EIO;
-                       mt9m001->exposure = ctrl->value;
-                       mt9m001->autoexposure = 0;
-               }
-               break;
-       case V4L2_CID_EXPOSURE_AUTO:
-               if (ctrl->value) {
+               } else {
                        const u16 vblank = 25;
-                       unsigned int total_h = mt9m001->rect.height +
+
+                       mt9m001->total_h = mt9m001->rect.height +
                                mt9m001->y_skip_top + vblank;
-                       if (reg_write(client, MT9M001_SHUTTER_WIDTH,
-                                     total_h) < 0)
+                       if (reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h) < 0)
                                return -EIO;
-                       qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
-                       mt9m001->exposure = (524 + (total_h - 1) *
-                                (qctrl->maximum - qctrl->minimum)) /
-                               1048 + qctrl->minimum;
-                       mt9m001->autoexposure = 1;
-               } else
-                       mt9m001->autoexposure = 0;
-               break;
+               }
+               return 0;
        }
-       return 0;
+       return -EINVAL;
 }
 
 /*
  * Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one
  */
-static int mt9m001_video_probe(struct soc_camera_device *icd,
+static int mt9m001_video_probe(struct soc_camera_link *icl,
                               struct i2c_client *client)
 {
        struct mt9m001 *mt9m001 = to_mt9m001(client);
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
        s32 data;
        unsigned long flags;
        int ret;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
        /* Enable the chip */
        data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
        dev_dbg(&client->dev, "write: %d\n", data);
@@ -661,18 +536,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
                dev_err(&client->dev, "Failed to initialise the camera\n");
 
        /* mt9m001_init() has reset the chip, returning registers to defaults */
-       mt9m001->gain = 64;
-       mt9m001->exposure = 255;
-
-       return ret;
+       return v4l2_ctrl_handler_setup(&mt9m001->hdl);
 }
 
-static void mt9m001_video_remove(struct soc_camera_device *icd)
+static void mt9m001_video_remove(struct soc_camera_link *icl)
 {
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-
-       dev_dbg(icd->pdev, "Video removed: %p, %p\n",
-               icd->parent, icd->vdev);
        if (icl->free_bus)
                icl->free_bus(icl);
 }
@@ -687,9 +555,12 @@ static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
        return 0;
 }
 
+static const struct v4l2_ctrl_ops mt9m001_ctrl_ops = {
+       .g_volatile_ctrl = mt9m001_g_volatile_ctrl,
+       .s_ctrl = mt9m001_s_ctrl,
+};
+
 static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
-       .g_ctrl         = mt9m001_g_ctrl,
-       .s_ctrl         = mt9m001_s_ctrl,
        .g_chip_ident   = mt9m001_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register     = mt9m001_g_register,
@@ -710,6 +581,40 @@ static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
        return 0;
 }
 
+static int mt9m001_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       /* MT9M001 has all capture_format parameters fixed */
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_MASTER;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
+static int mt9m001_s_mbus_config(struct v4l2_subdev *sd,
+                               const struct v4l2_mbus_config *cfg)
+{
+       const struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+       struct mt9m001 *mt9m001 = to_mt9m001(client);
+       unsigned int bps = soc_mbus_get_fmtdesc(mt9m001->fmt->code)->bits_per_sample;
+
+       if (icl->set_bus_param)
+               return icl->set_bus_param(icl, 1 << (bps - 1));
+
+       /*
+        * Without board specific bus width settings we only support the
+        * sensors native bus width
+        */
+       return bps == 10 ? 0 : -EINVAL;
+}
+
 static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
        .s_stream       = mt9m001_s_stream,
        .s_mbus_fmt     = mt9m001_s_fmt,
@@ -719,6 +624,8 @@ static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
        .g_crop         = mt9m001_g_crop,
        .cropcap        = mt9m001_cropcap,
        .enum_mbus_fmt  = mt9m001_enum_fmt,
+       .g_mbus_config  = mt9m001_g_mbus_config,
+       .s_mbus_config  = mt9m001_s_mbus_config,
 };
 
 static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
@@ -735,17 +642,10 @@ static int mt9m001_probe(struct i2c_client *client,
                         const struct i2c_device_id *did)
 {
        struct mt9m001 *mt9m001;
-       struct soc_camera_device *icd = client->dev.platform_data;
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-       struct soc_camera_link *icl;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "MT9M001: missing soc-camera data!\n");
-               return -EINVAL;
-       }
-
-       icl = to_soc_camera_link(icd);
        if (!icl) {
                dev_err(&client->dev, "MT9M001 driver needs platform data\n");
                return -EINVAL;
@@ -762,25 +662,40 @@ static int mt9m001_probe(struct i2c_client *client,
                return -ENOMEM;
 
        v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
+       v4l2_ctrl_handler_init(&mt9m001->hdl, 4);
+       v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
+                       V4L2_CID_GAIN, 0, 127, 1, 64);
+       mt9m001->exposure = v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
+                       V4L2_CID_EXPOSURE, 1, 255, 1, 255);
+       /*
+        * Simulated autoexposure. If enabled, we calculate shutter width
+        * ourselves in the driver based on vertical blanking and frame width
+        */
+       mt9m001->autoexposure = v4l2_ctrl_new_std_menu(&mt9m001->hdl,
+                       &mt9m001_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
+                       V4L2_EXPOSURE_AUTO);
+       mt9m001->subdev.ctrl_handler = &mt9m001->hdl;
+       if (mt9m001->hdl.error) {
+               int err = mt9m001->hdl.error;
 
-       /* Second stage probe - when a capture adapter is there */
-       icd->ops                = &mt9m001_ops;
+               kfree(mt9m001);
+               return err;
+       }
+       v4l2_ctrl_auto_cluster(2, &mt9m001->autoexposure,
+                                       V4L2_EXPOSURE_MANUAL, true);
 
+       /* Second stage probe - when a capture adapter is there */
        mt9m001->y_skip_top     = 0;
        mt9m001->rect.left      = MT9M001_COLUMN_SKIP;
        mt9m001->rect.top       = MT9M001_ROW_SKIP;
        mt9m001->rect.width     = MT9M001_MAX_WIDTH;
        mt9m001->rect.height    = MT9M001_MAX_HEIGHT;
 
-       /*
-        * Simulated autoexposure. If enabled, we calculate shutter width
-        * ourselves in the driver based on vertical blanking and frame width
-        */
-       mt9m001->autoexposure = 1;
-
-       ret = mt9m001_video_probe(icd, client);
+       ret = mt9m001_video_probe(icl, client);
        if (ret) {
-               icd->ops = NULL;
+               v4l2_ctrl_handler_free(&mt9m001->hdl);
                kfree(mt9m001);
        }
 
@@ -790,10 +705,11 @@ static int mt9m001_probe(struct i2c_client *client,
 static int mt9m001_remove(struct i2c_client *client)
 {
        struct mt9m001 *mt9m001 = to_mt9m001(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
 
-       icd->ops = NULL;
-       mt9m001_video_remove(icd);
+       v4l2_device_unregister_subdev(&mt9m001->subdev);
+       v4l2_ctrl_handler_free(&mt9m001->hdl);
+       mt9m001_video_remove(icl);
        kfree(mt9m001);
 
        return 0;
index 07af26e..f023cc0 100644 (file)
 #include <linux/log2.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
+#include <linux/v4l2-mediabus.h>
 
+#include <media/soc_camera.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
 
 /*
  * MT9M111, MT9M112 and MT9M131:
@@ -177,6 +179,8 @@ enum mt9m111_context {
 
 struct mt9m111 {
        struct v4l2_subdev subdev;
+       struct v4l2_ctrl_handler hdl;
+       struct v4l2_ctrl *gain;
        int model;      /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code
                         * from v4l2-chip-ident.h */
        enum mt9m111_context context;
@@ -185,13 +189,8 @@ struct mt9m111 {
        int power_count;
        const struct mt9m111_datafmt *fmt;
        int lastpage;   /* PageMap cache value */
-       unsigned int gain;
-       unsigned char autoexposure;
        unsigned char datawidth;
        unsigned int powered:1;
-       unsigned int hflip:1;
-       unsigned int vflip:1;
-       unsigned int autowhitebalance:1;
 };
 
 static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
@@ -363,21 +362,6 @@ static int mt9m111_reset(struct mt9m111 *mt9m111)
        return ret;
 }
 
-static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
-               SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
-               SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
-static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
-{
-       return 0;
-}
-
 static int mt9m111_make_rect(struct mt9m111 *mt9m111,
                             struct v4l2_rect *rect)
 {
@@ -660,50 +644,6 @@ static int mt9m111_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
-static const struct v4l2_queryctrl mt9m111_controls[] = {
-       {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Verticaly",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       }, {
-               .id             = V4L2_CID_HFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Horizontaly",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       }, {    /* gain = 1/32*val (=>gain=1 if val==32) */
-               .id             = V4L2_CID_GAIN,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Gain",
-               .minimum        = 0,
-               .maximum        = 63 * 2 * 2,
-               .step           = 1,
-               .default_value  = 32,
-               .flags          = V4L2_CTRL_FLAG_SLIDER,
-       }, {
-               .id             = V4L2_CID_EXPOSURE_AUTO,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Auto Exposure",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 1,
-       }
-};
-
-static struct soc_camera_ops mt9m111_ops = {
-       .query_bus_param        = mt9m111_query_bus_param,
-       .set_bus_param          = mt9m111_set_bus_param,
-       .controls               = mt9m111_controls,
-       .num_controls           = ARRAY_SIZE(mt9m111_controls),
-};
-
 static int mt9m111_set_flip(struct mt9m111 *mt9m111, int flip, int mask)
 {
        struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
@@ -744,7 +684,6 @@ static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain)
        if (gain > 63 * 2 * 2)
                return -EINVAL;
 
-       mt9m111->gain = gain;
        if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
                val = (1 << 10) | (1 << 9) | (gain / 4);
        else if ((gain >= 64) && (gain < 64 * 2))
@@ -758,118 +697,47 @@ static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain)
 static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int on)
 {
        struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
-       int ret;
 
        if (on)
-               ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
-       else
-               ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
-
-       if (!ret)
-               mt9m111->autoexposure = on;
-
-       return ret;
+               return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
+       return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
 }
 
 static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on)
 {
        struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
-       int ret;
 
        if (on)
-               ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
-       else
-               ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
-
-       if (!ret)
-               mt9m111->autowhitebalance = on;
-
-       return ret;
-}
-
-static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-       int data;
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               if (mt9m111->context == HIGHPOWER)
-                       data = reg_read(READ_MODE_B);
-               else
-                       data = reg_read(READ_MODE_A);
-
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !!(data & MT9M111_RMB_MIRROR_ROWS);
-               break;
-       case V4L2_CID_HFLIP:
-               if (mt9m111->context == HIGHPOWER)
-                       data = reg_read(READ_MODE_B);
-               else
-                       data = reg_read(READ_MODE_A);
-
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS);
-               break;
-       case V4L2_CID_GAIN:
-               data = mt9m111_get_global_gain(mt9m111);
-               if (data < 0)
-                       return data;
-               ctrl->value = data;
-               break;
-       case V4L2_CID_EXPOSURE_AUTO:
-               ctrl->value = mt9m111->autoexposure;
-               break;
-       case V4L2_CID_AUTO_WHITE_BALANCE:
-               ctrl->value = mt9m111->autowhitebalance;
-               break;
-       }
-       return 0;
+               return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
+       return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
 }
 
-static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-       struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-       const struct v4l2_queryctrl *qctrl;
-       int ret;
-
-       qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id);
-       if (!qctrl)
-               return -EINVAL;
+       struct mt9m111 *mt9m111 = container_of(ctrl->handler,
+                                              struct mt9m111, hdl);
 
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               mt9m111->vflip = ctrl->value;
-               ret = mt9m111_set_flip(mt9m111, ctrl->value,
+               return mt9m111_set_flip(mt9m111, ctrl->val,
                                        MT9M111_RMB_MIRROR_ROWS);
-               break;
        case V4L2_CID_HFLIP:
-               mt9m111->hflip = ctrl->value;
-               ret = mt9m111_set_flip(mt9m111, ctrl->value,
+               return mt9m111_set_flip(mt9m111, ctrl->val,
                                        MT9M111_RMB_MIRROR_COLS);
-               break;
        case V4L2_CID_GAIN:
-               ret = mt9m111_set_global_gain(mt9m111, ctrl->value);
-               break;
+               return mt9m111_set_global_gain(mt9m111, ctrl->val);
        case V4L2_CID_EXPOSURE_AUTO:
-               ret =  mt9m111_set_autoexposure(mt9m111, ctrl->value);
-               break;
+               return mt9m111_set_autoexposure(mt9m111, ctrl->val);
        case V4L2_CID_AUTO_WHITE_BALANCE:
-               ret =  mt9m111_set_autowhitebalance(mt9m111, ctrl->value);
-               break;
-       default:
-               ret = -EINVAL;
+               return mt9m111_set_autowhitebalance(mt9m111, ctrl->val);
        }
 
-       return ret;
+       return -EINVAL;
 }
 
 static int mt9m111_suspend(struct mt9m111 *mt9m111)
 {
-       mt9m111->gain = mt9m111_get_global_gain(mt9m111);
+       v4l2_ctrl_s_ctrl(mt9m111->gain, mt9m111_get_global_gain(mt9m111));
 
        return 0;
 }
@@ -879,11 +747,7 @@ static void mt9m111_restore_state(struct mt9m111 *mt9m111)
        mt9m111_set_context(mt9m111, mt9m111->context);
        mt9m111_set_pixfmt(mt9m111, mt9m111->fmt->code);
        mt9m111_setup_rect(mt9m111, &mt9m111->rect);
-       mt9m111_set_flip(mt9m111, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
-       mt9m111_set_flip(mt9m111, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
-       mt9m111_set_global_gain(mt9m111, mt9m111->gain);
-       mt9m111_set_autoexposure(mt9m111, mt9m111->autoexposure);
-       mt9m111_set_autowhitebalance(mt9m111, mt9m111->autowhitebalance);
+       v4l2_ctrl_handler_setup(&mt9m111->hdl);
 }
 
 static int mt9m111_resume(struct mt9m111 *mt9m111)
@@ -911,8 +775,6 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
                ret = mt9m111_reset(mt9m111);
        if (!ret)
                ret = mt9m111_set_context(mt9m111, mt9m111->context);
-       if (!ret)
-               ret = mt9m111_set_autoexposure(mt9m111, mt9m111->autoexposure);
        if (ret)
                dev_err(&client->dev, "mt9m111 init failed: %d\n", ret);
        return ret;
@@ -922,22 +784,12 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
  * Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one
  */
-static int mt9m111_video_probe(struct soc_camera_device *icd,
-                              struct i2c_client *client)
+static int mt9m111_video_probe(struct i2c_client *client)
 {
        struct mt9m111 *mt9m111 = to_mt9m111(client);
        s32 data;
        int ret;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
-       mt9m111->lastpage = -1;
-
-       mt9m111->autoexposure = 1;
-       mt9m111->autowhitebalance = 1;
-
        data = reg_read(CHIP_VERSION);
 
        switch (data) {
@@ -951,17 +803,16 @@ static int mt9m111_video_probe(struct soc_camera_device *icd,
                dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
                break;
        default:
-               ret = -ENODEV;
                dev_err(&client->dev,
                        "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n",
                        data);
-               goto ei2c;
+               return -ENODEV;
        }
 
        ret = mt9m111_init(mt9m111);
-
-ei2c:
-       return ret;
+       if (ret)
+               return ret;
+       return v4l2_ctrl_handler_setup(&mt9m111->hdl);
 }
 
 static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
@@ -998,9 +849,11 @@ out:
        return ret;
 }
 
+static const struct v4l2_ctrl_ops mt9m111_ctrl_ops = {
+       .s_ctrl = mt9m111_s_ctrl,
+};
+
 static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
-       .g_ctrl         = mt9m111_g_ctrl,
-       .s_ctrl         = mt9m111_s_ctrl,
        .g_chip_ident   = mt9m111_g_chip_ident,
        .s_power        = mt9m111_s_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1019,6 +872,21 @@ static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
        return 0;
 }
 
+static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
 static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
        .s_mbus_fmt     = mt9m111_s_fmt,
        .g_mbus_fmt     = mt9m111_g_fmt,
@@ -1027,6 +895,7 @@ static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
        .g_crop         = mt9m111_g_crop,
        .cropcap        = mt9m111_cropcap,
        .enum_mbus_fmt  = mt9m111_enum_fmt,
+       .g_mbus_config  = mt9m111_g_mbus_config,
 };
 
 static struct v4l2_subdev_ops mt9m111_subdev_ops = {
@@ -1038,17 +907,10 @@ static int mt9m111_probe(struct i2c_client *client,
                         const struct i2c_device_id *did)
 {
        struct mt9m111 *mt9m111;
-       struct soc_camera_device *icd = client->dev.platform_data;
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-       struct soc_camera_link *icl;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "mt9m111: soc-camera data missing!\n");
-               return -EINVAL;
-       }
-
-       icl = to_soc_camera_link(icd);
        if (!icl) {
                dev_err(&client->dev, "mt9m111: driver needs platform data\n");
                return -EINVAL;
@@ -1065,19 +927,37 @@ static int mt9m111_probe(struct i2c_client *client,
                return -ENOMEM;
 
        v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
+       v4l2_ctrl_handler_init(&mt9m111->hdl, 5);
+       v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
+                       V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
+       mt9m111->gain = v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
+                       V4L2_CID_GAIN, 0, 63 * 2 * 2, 1, 32);
+       v4l2_ctrl_new_std_menu(&mt9m111->hdl,
+                       &mt9m111_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
+                       V4L2_EXPOSURE_AUTO);
+       mt9m111->subdev.ctrl_handler = &mt9m111->hdl;
+       if (mt9m111->hdl.error) {
+               int err = mt9m111->hdl.error;
 
-       /* Second stage probe - when a capture adapter is there */
-       icd->ops                = &mt9m111_ops;
+               kfree(mt9m111);
+               return err;
+       }
 
+       /* Second stage probe - when a capture adapter is there */
        mt9m111->rect.left      = MT9M111_MIN_DARK_COLS;
        mt9m111->rect.top       = MT9M111_MIN_DARK_ROWS;
        mt9m111->rect.width     = MT9M111_MAX_WIDTH;
        mt9m111->rect.height    = MT9M111_MAX_HEIGHT;
        mt9m111->fmt            = &mt9m111_colour_fmts[0];
+       mt9m111->lastpage       = -1;
 
-       ret = mt9m111_video_probe(icd, client);
+       ret = mt9m111_video_probe(client);
        if (ret) {
-               icd->ops = NULL;
+               v4l2_ctrl_handler_free(&mt9m111->hdl);
                kfree(mt9m111);
        }
 
@@ -1087,9 +967,9 @@ static int mt9m111_probe(struct i2c_client *client,
 static int mt9m111_remove(struct i2c_client *client)
 {
        struct mt9m111 *mt9m111 = to_mt9m111(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
 
-       icd->ops = NULL;
+       v4l2_device_unregister_subdev(&mt9m111->subdev);
+       v4l2_ctrl_handler_free(&mt9m111->hdl);
        kfree(mt9m111);
 
        return 0;
index 30547cc..7ee84cc 100644 (file)
 #include <linux/log2.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
+#include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
 
 #include <media/soc_camera.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+
+/*
+ * ATTENTION: this driver still cannot be used outside of the soc-camera
+ * framework because of its PM implementation, using the video_device node.
+ * If hardware becomes available for testing, alternative PM approaches shall
+ * be considered and tested.
+ */
 
 /*
  * mt9t031 i2c address 0x5d
 #define MT9T031_COLUMN_SKIP            32
 #define MT9T031_ROW_SKIP               20
 
-#define MT9T031_BUS_PARAM      (SOCAM_PCLK_SAMPLE_RISING |     \
-       SOCAM_PCLK_SAMPLE_FALLING | SOCAM_HSYNC_ACTIVE_HIGH |   \
-       SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH |      \
-       SOCAM_MASTER | SOCAM_DATAWIDTH_10)
-
 struct mt9t031 {
        struct v4l2_subdev subdev;
+       struct v4l2_ctrl_handler hdl;
+       struct {
+               /* exposure/auto-exposure cluster */
+               struct v4l2_ctrl *autoexposure;
+               struct v4l2_ctrl *exposure;
+       };
        struct v4l2_rect rect;  /* Sensor window */
        int model;      /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
        u16 xskip;
        u16 yskip;
-       unsigned int gain;
+       unsigned int total_h;
        unsigned short y_skip_top;      /* Lines to skip at the top */
-       unsigned int exposure;
-       unsigned char autoexposure;
 };
 
 static struct mt9t031 *to_mt9t031(const struct i2c_client *client)
@@ -179,95 +187,6 @@ static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
        return 0;
 }
 
-static int mt9t031_set_bus_param(struct soc_camera_device *icd,
-                                unsigned long flags)
-{
-       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-
-       /* The caller should have queried our parameters, check anyway */
-       if (flags & ~MT9T031_BUS_PARAM)
-               return -EINVAL;
-
-       if (flags & SOCAM_PCLK_SAMPLE_FALLING)
-               reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
-       else
-               reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
-
-       return 0;
-}
-
-static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-
-       return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
-}
-
-enum {
-       MT9T031_CTRL_VFLIP,
-       MT9T031_CTRL_HFLIP,
-       MT9T031_CTRL_GAIN,
-       MT9T031_CTRL_EXPOSURE,
-       MT9T031_CTRL_EXPOSURE_AUTO,
-};
-
-static const struct v4l2_queryctrl mt9t031_controls[] = {
-       [MT9T031_CTRL_VFLIP] = {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Vertically",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-       [MT9T031_CTRL_HFLIP] = {
-               .id             = V4L2_CID_HFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Horizontally",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-       [MT9T031_CTRL_GAIN] = {
-               .id             = V4L2_CID_GAIN,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Gain",
-               .minimum        = 0,
-               .maximum        = 127,
-               .step           = 1,
-               .default_value  = 64,
-               .flags          = V4L2_CTRL_FLAG_SLIDER,
-       },
-       [MT9T031_CTRL_EXPOSURE] = {
-               .id             = V4L2_CID_EXPOSURE,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Exposure",
-               .minimum        = 1,
-               .maximum        = 255,
-               .step           = 1,
-               .default_value  = 255,
-               .flags          = V4L2_CTRL_FLAG_SLIDER,
-       },
-       [MT9T031_CTRL_EXPOSURE_AUTO] = {
-               .id             = V4L2_CID_EXPOSURE_AUTO,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Automatic Exposure",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 1,
-       }
-};
-
-static struct soc_camera_ops mt9t031_ops = {
-       .set_bus_param          = mt9t031_set_bus_param,
-       .query_bus_param        = mt9t031_query_bus_param,
-       .controls               = mt9t031_controls,
-       .num_controls           = ARRAY_SIZE(mt9t031_controls),
-};
-
 /* target must be _even_ */
 static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
 {
@@ -353,7 +272,7 @@ static int mt9t031_set_params(struct i2c_client *client,
 
        /*
         * The caller provides a supported format, as guaranteed by
-        * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap()
+        * .try_mbus_fmt(), soc_camera_s_crop() and soc_camera_cropcap()
         */
        if (ret >= 0)
                ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
@@ -364,17 +283,10 @@ static int mt9t031_set_params(struct i2c_client *client,
        if (ret >= 0)
                ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
                                rect->height + mt9t031->y_skip_top - 1);
-       if (ret >= 0 && mt9t031->autoexposure) {
-               unsigned int total_h = rect->height + mt9t031->y_skip_top + vblank;
-               ret = set_shutter(client, total_h);
-               if (ret >= 0) {
-                       const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
-                       const struct v4l2_queryctrl *qctrl =
-                               &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
-                       mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
-                                (qctrl->maximum - qctrl->minimum)) /
-                               shutter_max + qctrl->minimum;
-               }
+       if (ret >= 0 && v4l2_ctrl_g_ctrl(mt9t031->autoexposure) == V4L2_EXPOSURE_AUTO) {
+               mt9t031->total_h = rect->height + mt9t031->y_skip_top + vblank;
+
+               ret = set_shutter(client, mt9t031->total_h);
        }
 
        /* Re-enable register update, commit all changes */
@@ -543,71 +455,57 @@ static int mt9t031_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
-static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int mt9t031_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9t031 *mt9t031 = to_mt9t031(client);
-       int data;
+       struct mt9t031 *mt9t031 = container_of(ctrl->handler,
+                                              struct mt9t031, hdl);
+       const u32 shutter_max = MT9T031_MAX_HEIGHT + MT9T031_VERTICAL_BLANK;
+       s32 min, max;
 
        switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               data = reg_read(client, MT9T031_READ_MODE_2);
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !!(data & 0x8000);
-               break;
-       case V4L2_CID_HFLIP:
-               data = reg_read(client, MT9T031_READ_MODE_2);
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !!(data & 0x4000);
-               break;
        case V4L2_CID_EXPOSURE_AUTO:
-               ctrl->value = mt9t031->autoexposure;
-               break;
-       case V4L2_CID_GAIN:
-               ctrl->value = mt9t031->gain;
-               break;
-       case V4L2_CID_EXPOSURE:
-               ctrl->value = mt9t031->exposure;
+               min = mt9t031->exposure->minimum;
+               max = mt9t031->exposure->maximum;
+               mt9t031->exposure->val =
+                       (shutter_max / 2 + (mt9t031->total_h - 1) * (max - min))
+                               / shutter_max + min;
                break;
        }
        return 0;
 }
 
-static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+       struct mt9t031 *mt9t031 = container_of(ctrl->handler,
+                                              struct mt9t031, hdl);
+       struct v4l2_subdev *sd = &mt9t031->subdev;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct mt9t031 *mt9t031 = to_mt9t031(client);
-       const struct v4l2_queryctrl *qctrl;
+       struct v4l2_ctrl *exp = mt9t031->exposure;
        int data;
 
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               if (ctrl->value)
+               if (ctrl->val)
                        data = reg_set(client, MT9T031_READ_MODE_2, 0x8000);
                else
                        data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000);
                if (data < 0)
                        return -EIO;
-               break;
+               return 0;
        case V4L2_CID_HFLIP:
-               if (ctrl->value)
+               if (ctrl->val)
                        data = reg_set(client, MT9T031_READ_MODE_2, 0x4000);
                else
                        data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000);
                if (data < 0)
                        return -EIO;
-               break;
+               return 0;
        case V4L2_CID_GAIN:
-               qctrl = &mt9t031_controls[MT9T031_CTRL_GAIN];
-               if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
-                       return -EINVAL;
                /* See Datasheet Table 7, Gain settings. */
-               if (ctrl->value <= qctrl->default_value) {
+               if (ctrl->val <= ctrl->default_value) {
                        /* Pack it into 0..1 step 0.125, register values 0..8 */
-                       unsigned long range = qctrl->default_value - qctrl->minimum;
-                       data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
+                       unsigned long range = ctrl->default_value - ctrl->minimum;
+                       data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
 
                        dev_dbg(&client->dev, "Setting gain %d\n", data);
                        data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
@@ -616,9 +514,9 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
                } else {
                        /* Pack it into 1.125..128 variable step, register values 9..0x7860 */
                        /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
-                       unsigned long range = qctrl->maximum - qctrl->default_value - 1;
+                       unsigned long range = ctrl->maximum - ctrl->default_value - 1;
                        /* calculated gain: map 65..127 to 9..1024 step 0.125 */
-                       unsigned long gain = ((ctrl->value - qctrl->default_value - 1) *
+                       unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
                                               1015 + range / 2) / range + 9;
 
                        if (gain <= 32)         /* calculated gain 9..32 -> 9..32 */
@@ -635,19 +533,13 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
                        if (data < 0)
                                return -EIO;
                }
+               return 0;
 
-               /* Success */
-               mt9t031->gain = ctrl->value;
-               break;
-       case V4L2_CID_EXPOSURE:
-               qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
-               /* mt9t031 has maximum == default */
-               if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
-                       return -EINVAL;
-               else {
-                       const unsigned long range = qctrl->maximum - qctrl->minimum;
-                       const u32 shutter = ((ctrl->value - qctrl->minimum) * 1048 +
-                                            range / 2) / range + 1;
+       case V4L2_CID_EXPOSURE_AUTO:
+               if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
+                       unsigned int range = exp->maximum - exp->minimum;
+                       unsigned int shutter = ((exp->val - exp->minimum) * 1048 +
+                                                range / 2) / range + 1;
                        u32 old;
 
                        get_shutter(client, &old);
@@ -655,27 +547,15 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
                                old, shutter);
                        if (set_shutter(client, shutter) < 0)
                                return -EIO;
-                       mt9t031->exposure = ctrl->value;
-                       mt9t031->autoexposure = 0;
-               }
-               break;
-       case V4L2_CID_EXPOSURE_AUTO:
-               if (ctrl->value) {
+               } else {
                        const u16 vblank = MT9T031_VERTICAL_BLANK;
-                       const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
-                       unsigned int total_h = mt9t031->rect.height +
+                       mt9t031->total_h = mt9t031->rect.height +
                                mt9t031->y_skip_top + vblank;
 
-                       if (set_shutter(client, total_h) < 0)
+                       if (set_shutter(client, mt9t031->total_h) < 0)
                                return -EIO;
-                       qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
-                       mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
-                                (qctrl->maximum - qctrl->minimum)) /
-                               shutter_max + qctrl->minimum;
-                       mt9t031->autoexposure = 1;
-               } else
-                       mt9t031->autoexposure = 0;
-               break;
+               }
+               return 0;
        default:
                return -EINVAL;
        }
@@ -700,8 +580,7 @@ static int mt9t031_runtime_suspend(struct device *dev)
 static int mt9t031_runtime_resume(struct device *dev)
 {
        struct video_device *vdev = to_video_device(dev);
-       struct soc_camera_device *icd = dev_get_drvdata(vdev->parent);
-       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       struct v4l2_subdev *sd = soc_camera_vdev_to_subdev(vdev);
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct mt9t031 *mt9t031 = to_mt9t031(client);
 
@@ -734,6 +613,19 @@ static struct device_type mt9t031_dev_type = {
        .pm     = &mt9t031_dev_pm_ops,
 };
 
+static int mt9t031_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct video_device *vdev = soc_camera_i2c_to_vdev(client);
+
+       if (on)
+               vdev->dev.type = &mt9t031_dev_type;
+       else
+               vdev->dev.type = NULL;
+
+       return 0;
+}
+
 /*
  * Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one
@@ -741,7 +633,6 @@ static struct device_type mt9t031_dev_type = {
 static int mt9t031_video_probe(struct i2c_client *client)
 {
        struct mt9t031 *mt9t031 = to_mt9t031(client);
-       struct video_device *vdev = soc_camera_i2c_to_vdev(client);
        s32 data;
        int ret;
 
@@ -768,11 +659,7 @@ static int mt9t031_video_probe(struct i2c_client *client)
        if (ret < 0)
                dev_err(&client->dev, "Failed to initialise the camera\n");
        else
-               vdev->dev.type = &mt9t031_dev_type;
-
-       /* mt9t031_idle() has reset the chip to default. */
-       mt9t031->exposure = 255;
-       mt9t031->gain = 64;
+               v4l2_ctrl_handler_setup(&mt9t031->hdl);
 
        return ret;
 }
@@ -787,10 +674,14 @@ static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
        return 0;
 }
 
+static const struct v4l2_ctrl_ops mt9t031_ctrl_ops = {
+       .g_volatile_ctrl = mt9t031_g_volatile_ctrl,
+       .s_ctrl = mt9t031_s_ctrl,
+};
+
 static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
-       .g_ctrl         = mt9t031_g_ctrl,
-       .s_ctrl         = mt9t031_s_ctrl,
        .g_chip_ident   = mt9t031_g_chip_ident,
+       .s_power        = mt9t031_s_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register     = mt9t031_g_register,
        .s_register     = mt9t031_s_register,
@@ -807,6 +698,34 @@ static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
        return 0;
 }
 
+static int mt9t031_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
+               V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
+static int mt9t031_s_mbus_config(struct v4l2_subdev *sd,
+                               const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       if (soc_camera_apply_board_flags(icl, cfg) &
+           V4L2_MBUS_PCLK_SAMPLE_FALLING)
+               return reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
+       else
+               return reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
+}
+
 static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
        .s_stream       = mt9t031_s_stream,
        .s_mbus_fmt     = mt9t031_s_fmt,
@@ -816,6 +735,8 @@ static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
        .g_crop         = mt9t031_g_crop,
        .cropcap        = mt9t031_cropcap,
        .enum_mbus_fmt  = mt9t031_enum_fmt,
+       .g_mbus_config  = mt9t031_g_mbus_config,
+       .s_mbus_config  = mt9t031_s_mbus_config,
 };
 
 static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
@@ -832,18 +753,13 @@ static int mt9t031_probe(struct i2c_client *client,
                         const struct i2c_device_id *did)
 {
        struct mt9t031 *mt9t031;
-       struct soc_camera_device *icd = client->dev.platform_data;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
        int ret;
 
-       if (icd) {
-               struct soc_camera_link *icl = to_soc_camera_link(icd);
-               if (!icl) {
-                       dev_err(&client->dev, "MT9T031 driver needs platform data\n");
-                       return -EINVAL;
-               }
-
-               icd->ops = &mt9t031_ops;
+       if (!icl) {
+               dev_err(&client->dev, "MT9T031 driver needs platform data\n");
+               return -EINVAL;
        }
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
@@ -857,6 +773,33 @@ static int mt9t031_probe(struct i2c_client *client,
                return -ENOMEM;
 
        v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
+       v4l2_ctrl_handler_init(&mt9t031->hdl, 5);
+       v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
+                       V4L2_CID_GAIN, 0, 127, 1, 64);
+
+       /*
+        * Simulated autoexposure. If enabled, we calculate shutter width
+        * ourselves in the driver based on vertical blanking and frame width
+        */
+       mt9t031->autoexposure = v4l2_ctrl_new_std_menu(&mt9t031->hdl,
+                       &mt9t031_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
+                       V4L2_EXPOSURE_AUTO);
+       mt9t031->exposure = v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
+                       V4L2_CID_EXPOSURE, 1, 255, 1, 255);
+
+       mt9t031->subdev.ctrl_handler = &mt9t031->hdl;
+       if (mt9t031->hdl.error) {
+               int err = mt9t031->hdl.error;
+
+               kfree(mt9t031);
+               return err;
+       }
+       v4l2_ctrl_auto_cluster(2, &mt9t031->autoexposure,
+                               V4L2_EXPOSURE_MANUAL, true);
 
        mt9t031->y_skip_top     = 0;
        mt9t031->rect.left      = MT9T031_COLUMN_SKIP;
@@ -864,12 +807,6 @@ static int mt9t031_probe(struct i2c_client *client,
        mt9t031->rect.width     = MT9T031_MAX_WIDTH;
        mt9t031->rect.height    = MT9T031_MAX_HEIGHT;
 
-       /*
-        * Simulated autoexposure. If enabled, we calculate shutter width
-        * ourselves in the driver based on vertical blanking and frame width
-        */
-       mt9t031->autoexposure = 1;
-
        mt9t031->xskip = 1;
        mt9t031->yskip = 1;
 
@@ -880,8 +817,7 @@ static int mt9t031_probe(struct i2c_client *client,
        mt9t031_disable(client);
 
        if (ret) {
-               if (icd)
-                       icd->ops = NULL;
+               v4l2_ctrl_handler_free(&mt9t031->hdl);
                kfree(mt9t031);
        }
 
@@ -891,10 +827,9 @@ static int mt9t031_probe(struct i2c_client *client,
 static int mt9t031_remove(struct i2c_client *client)
 {
        struct mt9t031 *mt9t031 = to_mt9t031(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
 
-       if (icd)
-               icd->ops = NULL;
+       v4l2_device_unregister_subdev(&mt9t031->subdev);
+       v4l2_ctrl_handler_free(&mt9t031->hdl);
        kfree(mt9t031);
 
        return 0;
index d2e0a50..32114a3 100644 (file)
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
 
 #include <media/mt9t112.h>
 #include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
 
 /* #define EXT_CLOCK 24000000 */
 
 /************************************************************************
-
-
                        macro
-
-
 ************************************************************************/
 /*
  * frame size
 #define VAR8(id, offset) _VAR(id, offset, 0x8000)
 
 /************************************************************************
-
-
                        struct
-
-
 ************************************************************************/
-struct mt9t112_frame_size {
-       u16 width;
-       u16 height;
-};
-
 struct mt9t112_format {
        enum v4l2_mbus_pixelcode code;
        enum v4l2_colorspace colorspace;
@@ -102,21 +89,17 @@ struct mt9t112_priv {
        struct v4l2_subdev               subdev;
        struct mt9t112_camera_info      *info;
        struct i2c_client               *client;
-       struct soc_camera_device         icd;
-       struct mt9t112_frame_size        frame;
+       struct v4l2_rect                 frame;
        const struct mt9t112_format     *format;
        int                              model;
        u32                              flags;
 /* for flags */
-#define INIT_DONE  (1<<0)
+#define INIT_DONE      (1 << 0)
+#define PCLK_RISING    (1 << 1)
 };
 
 /************************************************************************
-
-
                        supported format
-
-
 ************************************************************************/
 
 static const struct mt9t112_format mt9t112_cfmts[] = {
@@ -154,11 +137,7 @@ static const struct mt9t112_format mt9t112_cfmts[] = {
 };
 
 /************************************************************************
-
-
                        general function
-
-
 ************************************************************************/
 static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
 {
@@ -326,50 +305,47 @@ static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
        n = (n >> 8) & 0x003f;
 
        enable = ((6000 > ext) || (54000 < ext)) ? "X" : "";
-       dev_info(&client->dev, "EXTCLK          : %10u K %s\n", ext, enable);
+       dev_dbg(&client->dev, "EXTCLK          : %10u K %s\n", ext, enable);
 
        vco = 2 * m * ext / (n+1);
        enable = ((384000 > vco) || (768000 < vco)) ? "X" : "";
-       dev_info(&client->dev, "VCO             : %10u K %s\n", vco, enable);
+       dev_dbg(&client->dev, "VCO             : %10u K %s\n", vco, enable);
 
        clk = vco / (p1+1) / (p2+1);
        enable = (96000 < clk) ? "X" : "";
-       dev_info(&client->dev, "PIXCLK          : %10u K %s\n", clk, enable);
+       dev_dbg(&client->dev, "PIXCLK          : %10u K %s\n", clk, enable);
 
        clk = vco / (p3+1);
        enable = (768000 < clk) ? "X" : "";
-       dev_info(&client->dev, "MIPICLK         : %10u K %s\n", clk, enable);
+       dev_dbg(&client->dev, "MIPICLK         : %10u K %s\n", clk, enable);
 
        clk = vco / (p6+1);
        enable = (96000 < clk) ? "X" : "";
-       dev_info(&client->dev, "MCU CLK         : %10u K %s\n", clk, enable);
+       dev_dbg(&client->dev, "MCU CLK         : %10u K %s\n", clk, enable);
 
        clk = vco / (p5+1);
        enable = (54000 < clk) ? "X" : "";
-       dev_info(&client->dev, "SOC CLK         : %10u K %s\n", clk, enable);
+       dev_dbg(&client->dev, "SOC CLK         : %10u K %s\n", clk, enable);
 
        clk = vco / (p4+1);
        enable = (70000 < clk) ? "X" : "";
-       dev_info(&client->dev, "Sensor CLK      : %10u K %s\n", clk, enable);
+       dev_dbg(&client->dev, "Sensor CLK      : %10u K %s\n", clk, enable);
 
        clk = vco / (p7+1);
-       dev_info(&client->dev, "External sensor : %10u K\n", clk);
+       dev_dbg(&client->dev, "External sensor : %10u K\n", clk);
 
        clk = ext / (n+1);
        enable = ((2000 > clk) || (24000 < clk)) ? "X" : "";
-       dev_info(&client->dev, "PFD             : %10u K %s\n", clk, enable);
+       dev_dbg(&client->dev, "PFD             : %10u K %s\n", clk, enable);
 
        return 0;
 }
 #endif
 
-static void mt9t112_frame_check(u32 *width, u32 *height)
+static void mt9t112_frame_check(u32 *width, u32 *height, u32 *left, u32 *top)
 {
-       if (*width > MAX_WIDTH)
-               *width = MAX_WIDTH;
-
-       if (*height > MAX_HEIGHT)
-               *height = MAX_HEIGHT;
+       soc_camera_limit_side(left, width, 0, 0, MAX_WIDTH);
+       soc_camera_limit_side(top, height, 0, 0, MAX_HEIGHT);
 }
 
 static int mt9t112_set_a_frame_size(const struct i2c_client *client,
@@ -758,48 +734,7 @@ static int mt9t112_init_camera(const struct i2c_client *client)
 }
 
 /************************************************************************
-
-
-                       soc_camera_ops
-
-
-************************************************************************/
-static int mt9t112_set_bus_param(struct soc_camera_device *icd,
-                                unsigned long  flags)
-{
-       return 0;
-}
-
-static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd)
-{
-       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-       struct mt9t112_priv *priv = to_mt9t112(client);
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       unsigned long flags = SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH |
-               SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH;
-
-       flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ?
-               SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING;
-
-       if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8)
-               flags |= SOCAM_DATAWIDTH_8;
-       else
-               flags |= SOCAM_DATAWIDTH_10;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
-static struct soc_camera_ops mt9t112_ops = {
-       .set_bus_param          = mt9t112_set_bus_param,
-       .query_bus_param        = mt9t112_query_bus_param,
-};
-
-/************************************************************************
-
-
                        v4l2_subdev_core_ops
-
-
 ************************************************************************/
 static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
                                struct v4l2_dbg_chip_ident *id)
@@ -850,11 +785,7 @@ static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
 
 
 /************************************************************************
-
-
                        v4l2_subdev_video_ops
-
-
 ************************************************************************/
 static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
 {
@@ -877,8 +808,7 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
        }
 
        if (!(priv->flags & INIT_DONE)) {
-               u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE &
-                            priv->info->flags) ? 0x0001 : 0x0000;
+               u16 param = PCLK_RISING & priv->flags ? 0x0001 : 0x0000;
 
                ECHECKER(ret, mt9t112_init_camera(client));
 
@@ -910,19 +840,12 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
        return ret;
 }
 
-static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
+static int mt9t112_set_params(struct mt9t112_priv *priv,
+                             const struct v4l2_rect *rect,
                              enum v4l2_mbus_pixelcode code)
 {
-       struct mt9t112_priv *priv = to_mt9t112(client);
        int i;
 
-       priv->format = NULL;
-
-       /*
-        * frame size check
-        */
-       mt9t112_frame_check(&width, &height);
-
        /*
         * get color format
         */
@@ -933,8 +856,13 @@ static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
        if (i == ARRAY_SIZE(mt9t112_cfmts))
                return -EINVAL;
 
-       priv->frame.width  = (u16)width;
-       priv->frame.height = (u16)height;
+       priv->frame  = *rect;
+
+       /*
+        * frame size check
+        */
+       mt9t112_frame_check(&priv->frame.width, &priv->frame.height,
+                           &priv->frame.left, &priv->frame.top);
 
        priv->format = mt9t112_cfmts + i;
 
@@ -945,9 +873,12 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 {
        a->bounds.left                  = 0;
        a->bounds.top                   = 0;
-       a->bounds.width                 = VGA_WIDTH;
-       a->bounds.height                = VGA_HEIGHT;
-       a->defrect                      = a->bounds;
+       a->bounds.width                 = MAX_WIDTH;
+       a->bounds.height                = MAX_HEIGHT;
+       a->defrect.left                 = 0;
+       a->defrect.top                  = 0;
+       a->defrect.width                = VGA_WIDTH;
+       a->defrect.height               = VGA_HEIGHT;
        a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        a->pixelaspect.numerator        = 1;
        a->pixelaspect.denominator      = 1;
@@ -957,11 +888,11 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 
 static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
-       a->c.left       = 0;
-       a->c.top        = 0;
-       a->c.width      = VGA_WIDTH;
-       a->c.height     = VGA_HEIGHT;
-       a->type         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+
+       a->c    = priv->frame;
+       a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
        return 0;
 }
@@ -969,10 +900,10 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
        struct v4l2_rect *rect = &a->c;
 
-       return mt9t112_set_params(client, rect->width, rect->height,
-                                V4L2_MBUS_FMT_UYVY8_2X8);
+       return mt9t112_set_params(priv, rect, priv->format->code);
 }
 
 static int mt9t112_g_fmt(struct v4l2_subdev *sd,
@@ -981,16 +912,9 @@ static int mt9t112_g_fmt(struct v4l2_subdev *sd,
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct mt9t112_priv *priv = to_mt9t112(client);
 
-       if (!priv->format) {
-               int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT,
-                                            V4L2_MBUS_FMT_UYVY8_2X8);
-               if (ret < 0)
-                       return ret;
-       }
-
        mf->width       = priv->frame.width;
        mf->height      = priv->frame.height;
-       /* TODO: set colorspace */
+       mf->colorspace  = priv->format->colorspace;
        mf->code        = priv->format->code;
        mf->field       = V4L2_FIELD_NONE;
 
@@ -1001,17 +925,42 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd,
                         struct v4l2_mbus_framefmt *mf)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+       struct v4l2_rect rect = {
+               .width = mf->width,
+               .height = mf->height,
+               .left = priv->frame.left,
+               .top = priv->frame.top,
+       };
+       int ret;
+
+       ret = mt9t112_set_params(priv, &rect, mf->code);
+
+       if (!ret)
+               mf->colorspace = priv->format->colorspace;
 
-       /* TODO: set colorspace */
-       return mt9t112_set_params(client, mf->width, mf->height, mf->code);
+       return ret;
 }
 
 static int mt9t112_try_fmt(struct v4l2_subdev *sd,
                           struct v4l2_mbus_framefmt *mf)
 {
-       mt9t112_frame_check(&mf->width, &mf->height);
+       unsigned int top, left;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++)
+               if (mt9t112_cfmts[i].code == mf->code)
+                       break;
+
+       if (i == ARRAY_SIZE(mt9t112_cfmts)) {
+               mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
+               mf->colorspace = V4L2_COLORSPACE_JPEG;
+       } else {
+               mf->colorspace  = mt9t112_cfmts[i].colorspace;
+       }
+
+       mt9t112_frame_check(&mf->width, &mf->height, &left, &top);
 
-       /* TODO: set colorspace */
        mf->field = V4L2_FIELD_NONE;
 
        return 0;
@@ -1024,6 +973,35 @@ static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
                return -EINVAL;
 
        *code = mt9t112_cfmts[index].code;
+
+       return 0;
+}
+
+static int mt9t112_g_mbus_config(struct v4l2_subdev *sd,
+                                struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH |
+               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
+static int mt9t112_s_mbus_config(struct v4l2_subdev *sd,
+                                const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+       struct mt9t112_priv *priv = to_mt9t112(client);
+
+       if (soc_camera_apply_board_flags(icl, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING)
+               priv->flags |= PCLK_RISING;
+
        return 0;
 }
 
@@ -1036,31 +1014,24 @@ static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
        .g_crop         = mt9t112_g_crop,
        .s_crop         = mt9t112_s_crop,
        .enum_mbus_fmt  = mt9t112_enum_fmt,
+       .g_mbus_config  = mt9t112_g_mbus_config,
+       .s_mbus_config  = mt9t112_s_mbus_config,
 };
 
 /************************************************************************
-
-
                        i2c driver
-
-
 ************************************************************************/
 static struct v4l2_subdev_ops mt9t112_subdev_ops = {
        .core   = &mt9t112_subdev_core_ops,
        .video  = &mt9t112_subdev_video_ops,
 };
 
-static int mt9t112_camera_probe(struct soc_camera_device *icd,
-                               struct i2c_client *client)
+static int mt9t112_camera_probe(struct i2c_client *client)
 {
        struct mt9t112_priv *priv = to_mt9t112(client);
        const char          *devname;
        int                  chipid;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
        /*
         * check and show chip ID
         */
@@ -1088,20 +1059,21 @@ static int mt9t112_camera_probe(struct soc_camera_device *icd,
 static int mt9t112_probe(struct i2c_client *client,
                         const struct i2c_device_id *did)
 {
-       struct mt9t112_priv        *priv;
-       struct soc_camera_device   *icd = client->dev.platform_data;
-       struct soc_camera_link     *icl;
-       int                         ret;
+       struct mt9t112_priv *priv;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+       struct v4l2_rect rect = {
+               .width = VGA_WIDTH,
+               .height = VGA_HEIGHT,
+               .left = (MAX_WIDTH - VGA_WIDTH) / 2,
+               .top = (MAX_HEIGHT - VGA_HEIGHT) / 2,
+       };
+       int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "mt9t112: missing soc-camera data!\n");
+       if (!icl || !icl->priv) {
+               dev_err(&client->dev, "mt9t112: missing platform data!\n");
                return -EINVAL;
        }
 
-       icl = to_soc_camera_link(icd);
-       if (!icl || !icl->priv)
-               return -EINVAL;
-
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
@@ -1110,13 +1082,12 @@ static int mt9t112_probe(struct i2c_client *client,
 
        v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
 
-       icd->ops = &mt9t112_ops;
-
-       ret = mt9t112_camera_probe(icd, client);
-       if (ret) {
-               icd->ops = NULL;
+       ret = mt9t112_camera_probe(client);
+       if (ret)
                kfree(priv);
-       }
+
+       /* Cannot fail: using the default supported pixel code */
+       mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
 
        return ret;
 }
@@ -1124,9 +1095,7 @@ static int mt9t112_probe(struct i2c_client *client,
 static int mt9t112_remove(struct i2c_client *client)
 {
        struct mt9t112_priv *priv = to_mt9t112(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
 
-       icd->ops = NULL;
        kfree(priv);
        return 0;
 }
@@ -1147,11 +1116,7 @@ static struct i2c_driver mt9t112_i2c_driver = {
 };
 
 /************************************************************************
-
-
                        module function
-
-
 ************************************************************************/
 static int __init mt9t112_module_init(void)
 {
index 51b0fcc..b6a29f7 100644 (file)
 #include <linux/delay.h>
 #include <linux/log2.h>
 
+#include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
+#include <media/v4l2-ctrls.h>
 
 /*
  * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
@@ -100,6 +102,17 @@ static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
 
 struct mt9v022 {
        struct v4l2_subdev subdev;
+       struct v4l2_ctrl_handler hdl;
+       struct {
+               /* exposure/auto-exposure cluster */
+               struct v4l2_ctrl *autoexposure;
+               struct v4l2_ctrl *exposure;
+       };
+       struct {
+               /* gain/auto-gain cluster */
+               struct v4l2_ctrl *autogain;
+               struct v4l2_ctrl *gain;
+       };
        struct v4l2_rect rect;  /* Sensor window */
        const struct mt9v022_datafmt *fmt;
        const struct mt9v022_datafmt *fmts;
@@ -178,6 +191,8 @@ static int mt9v022_init(struct i2c_client *client)
                ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
        if (!ret)
                ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
+       if (!ret)
+               return v4l2_ctrl_handler_setup(&mt9v022->hdl);
 
        return ret;
 }
@@ -199,78 +214,6 @@ static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
        return 0;
 }
 
-static int mt9v022_set_bus_param(struct soc_camera_device *icd,
-                                unsigned long flags)
-{
-       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-       struct mt9v022 *mt9v022 = to_mt9v022(client);
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
-       int ret;
-       u16 pixclk = 0;
-
-       /* Only one width bit may be set */
-       if (!is_power_of_2(width_flag))
-               return -EINVAL;
-
-       if (icl->set_bus_param) {
-               ret = icl->set_bus_param(icl, width_flag);
-               if (ret)
-                       return ret;
-       } else {
-               /*
-                * Without board specific bus width settings we only support the
-                * sensors native bus width
-                */
-               if (width_flag != SOCAM_DATAWIDTH_10)
-                       return -EINVAL;
-       }
-
-       flags = soc_camera_apply_sensor_flags(icl, flags);
-
-       if (flags & SOCAM_PCLK_SAMPLE_FALLING)
-               pixclk |= 0x10;
-
-       if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
-               pixclk |= 0x1;
-
-       if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
-               pixclk |= 0x2;
-
-       ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
-       if (ret < 0)
-               return ret;
-
-       if (!(flags & SOCAM_MASTER))
-               mt9v022->chip_control &= ~0x8;
-
-       ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
-       if (ret < 0)
-               return ret;
-
-       dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
-               pixclk, mt9v022->chip_control);
-
-       return 0;
-}
-
-static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       unsigned int flags = SOCAM_MASTER | SOCAM_SLAVE |
-               SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
-               SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
-               SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
-               SOCAM_DATA_ACTIVE_HIGH;
-
-       if (icl->query_bus_param)
-               flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
-       else
-               flags |= SOCAM_DATAWIDTH_10;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
 static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -389,7 +332,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
 
        /*
         * The caller provides a supported format, as verified per call to
-        * icd->try_fmt(), datawidth is from our supported format list
+        * .try_mbus_fmt(), datawidth is from our supported format list
         */
        switch (mf->code) {
        case V4L2_MBUS_FMT_Y8_1X8:
@@ -502,236 +445,131 @@ static int mt9v022_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
-static const struct v4l2_queryctrl mt9v022_controls[] = {
-       {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Vertically",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       }, {
-               .id             = V4L2_CID_HFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Horizontally",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       }, {
-               .id             = V4L2_CID_GAIN,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Analog Gain",
-               .minimum        = 64,
-               .maximum        = 127,
-               .step           = 1,
-               .default_value  = 64,
-               .flags          = V4L2_CTRL_FLAG_SLIDER,
-       }, {
-               .id             = V4L2_CID_EXPOSURE,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Exposure",
-               .minimum        = 1,
-               .maximum        = 255,
-               .step           = 1,
-               .default_value  = 255,
-               .flags          = V4L2_CTRL_FLAG_SLIDER,
-       }, {
-               .id             = V4L2_CID_AUTOGAIN,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Automatic Gain",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 1,
-       }, {
-               .id             = V4L2_CID_EXPOSURE_AUTO,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Automatic Exposure",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 1,
-       }
-};
-
-static struct soc_camera_ops mt9v022_ops = {
-       .set_bus_param          = mt9v022_set_bus_param,
-       .query_bus_param        = mt9v022_query_bus_param,
-       .controls               = mt9v022_controls,
-       .num_controls           = ARRAY_SIZE(mt9v022_controls),
-};
-
-static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 {
+       struct mt9v022 *mt9v022 = container_of(ctrl->handler,
+                                              struct mt9v022, hdl);
+       struct v4l2_subdev *sd = &mt9v022->subdev;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       const struct v4l2_queryctrl *qctrl;
+       struct v4l2_ctrl *gain = mt9v022->gain;
+       struct v4l2_ctrl *exp = mt9v022->exposure;
        unsigned long range;
        int data;
 
-       qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
-
        switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               data = reg_read(client, MT9V022_READ_MODE);
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !!(data & 0x10);
-               break;
-       case V4L2_CID_HFLIP:
-               data = reg_read(client, MT9V022_READ_MODE);
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !!(data & 0x20);
-               break;
-       case V4L2_CID_EXPOSURE_AUTO:
-               data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !!(data & 0x1);
-               break;
        case V4L2_CID_AUTOGAIN:
-               data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !!(data & 0x2);
-               break;
-       case V4L2_CID_GAIN:
                data = reg_read(client, MT9V022_ANALOG_GAIN);
                if (data < 0)
                        return -EIO;
 
-               range = qctrl->maximum - qctrl->minimum;
-               ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum;
-
-               break;
-       case V4L2_CID_EXPOSURE:
+               range = gain->maximum - gain->minimum;
+               gain->val = ((data - 16) * range + 24) / 48 + gain->minimum;
+               return 0;
+       case V4L2_CID_EXPOSURE_AUTO:
                data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
                if (data < 0)
                        return -EIO;
 
-               range = qctrl->maximum - qctrl->minimum;
-               ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum;
-
-               break;
+               range = exp->maximum - exp->minimum;
+               exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
+               return 0;
        }
-       return 0;
+       return -EINVAL;
 }
 
-static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-       int data;
+       struct mt9v022 *mt9v022 = container_of(ctrl->handler,
+                                              struct mt9v022, hdl);
+       struct v4l2_subdev *sd = &mt9v022->subdev;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       const struct v4l2_queryctrl *qctrl;
-
-       qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
-       if (!qctrl)
-               return -EINVAL;
+       int data;
 
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               if (ctrl->value)
+               if (ctrl->val)
                        data = reg_set(client, MT9V022_READ_MODE, 0x10);
                else
                        data = reg_clear(client, MT9V022_READ_MODE, 0x10);
                if (data < 0)
                        return -EIO;
-               break;
+               return 0;
        case V4L2_CID_HFLIP:
-               if (ctrl->value)
+               if (ctrl->val)
                        data = reg_set(client, MT9V022_READ_MODE, 0x20);
                else
                        data = reg_clear(client, MT9V022_READ_MODE, 0x20);
                if (data < 0)
                        return -EIO;
-               break;
-       case V4L2_CID_GAIN:
-               /* mt9v022 has minimum == default */
-               if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
-                       return -EINVAL;
-               else {
-                       unsigned long range = qctrl->maximum - qctrl->minimum;
+               return 0;
+       case V4L2_CID_AUTOGAIN:
+               if (ctrl->val) {
+                       if (reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
+                               return -EIO;
+               } else {
+                       struct v4l2_ctrl *gain = mt9v022->gain;
+                       /* mt9v022 has minimum == default */
+                       unsigned long range = gain->maximum - gain->minimum;
                        /* Valid values 16 to 64, 32 to 64 must be even. */
-                       unsigned long gain = ((ctrl->value - qctrl->minimum) *
+                       unsigned long gain_val = ((gain->val - gain->minimum) *
                                              48 + range / 2) / range + 16;
-                       if (gain >= 32)
-                               gain &= ~1;
+
+                       if (gain_val >= 32)
+                               gain_val &= ~1;
+
                        /*
                         * The user wants to set gain manually, hope, she
                         * knows, what she's doing... Switch AGC off.
                         */
-
                        if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
                                return -EIO;
 
                        dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
-                               reg_read(client, MT9V022_ANALOG_GAIN), gain);
-                       if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
+                               reg_read(client, MT9V022_ANALOG_GAIN), gain_val);
+                       if (reg_write(client, MT9V022_ANALOG_GAIN, gain_val) < 0)
                                return -EIO;
                }
-               break;
-       case V4L2_CID_EXPOSURE:
-               /* mt9v022 has maximum == default */
-               if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
-                       return -EINVAL;
-               else {
-                       unsigned long range = qctrl->maximum - qctrl->minimum;
-                       unsigned long shutter = ((ctrl->value - qctrl->minimum) *
-                                                479 + range / 2) / range + 1;
+               return 0;
+       case V4L2_CID_EXPOSURE_AUTO:
+               if (ctrl->val == V4L2_EXPOSURE_AUTO) {
+                       data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
+               } else {
+                       struct v4l2_ctrl *exp = mt9v022->exposure;
+                       unsigned long range = exp->maximum - exp->minimum;
+                       unsigned long shutter = ((exp->val - exp->minimum) *
+                                       479 + range / 2) / range + 1;
+
                        /*
                         * The user wants to set shutter width manually, hope,
                         * she knows, what she's doing... Switch AEC off.
                         */
-
-                       if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
+                       data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
+                       if (data < 0)
                                return -EIO;
-
                        dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
-                               reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
-                               shutter);
+                                       reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
+                                       shutter);
                        if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
-                                     shutter) < 0)
+                                               shutter) < 0)
                                return -EIO;
                }
-               break;
-       case V4L2_CID_AUTOGAIN:
-               if (ctrl->value)
-                       data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
-               else
-                       data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
-               if (data < 0)
-                       return -EIO;
-               break;
-       case V4L2_CID_EXPOSURE_AUTO:
-               if (ctrl->value)
-                       data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
-               else
-                       data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
-               if (data < 0)
-                       return -EIO;
-               break;
+               return 0;
        }
-       return 0;
+       return -EINVAL;
 }
 
 /*
  * Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one
  */
-static int mt9v022_video_probe(struct soc_camera_device *icd,
-                              struct i2c_client *client)
+static int mt9v022_video_probe(struct i2c_client *client)
 {
        struct mt9v022 *mt9v022 = to_mt9v022(client);
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        s32 data;
        int ret;
        unsigned long flags;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
        /* Read out the chip version register */
        data = reg_read(client, MT9V022_CHIP_VERSION);
 
@@ -805,16 +643,6 @@ ei2c:
        return ret;
 }
 
-static void mt9v022_video_remove(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-
-       dev_dbg(icd->pdev, "Video removed: %p, %p\n",
-               icd->parent, icd->vdev);
-       if (icl->free_bus)
-               icl->free_bus(icl);
-}
-
 static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -825,9 +653,12 @@ static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
        return 0;
 }
 
+static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = {
+       .g_volatile_ctrl = mt9v022_g_volatile_ctrl,
+       .s_ctrl = mt9v022_s_ctrl,
+};
+
 static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
-       .g_ctrl         = mt9v022_g_ctrl,
-       .s_ctrl         = mt9v022_s_ctrl,
        .g_chip_ident   = mt9v022_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register     = mt9v022_g_register,
@@ -848,6 +679,72 @@ static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
        return 0;
 }
 
+static int mt9v022_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE |
+               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
+static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
+                                const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+       struct mt9v022 *mt9v022 = to_mt9v022(client);
+       unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
+       unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample;
+       int ret;
+       u16 pixclk = 0;
+
+       if (icl->set_bus_param) {
+               ret = icl->set_bus_param(icl, 1 << (bps - 1));
+               if (ret)
+                       return ret;
+       } else if (bps != 10) {
+               /*
+                * Without board specific bus width settings we only support the
+                * sensors native bus width
+                */
+               return -EINVAL;
+       }
+
+       if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
+               pixclk |= 0x10;
+
+       if (!(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH))
+               pixclk |= 0x1;
+
+       if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
+               pixclk |= 0x2;
+
+       ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
+       if (ret < 0)
+               return ret;
+
+       if (!(flags & V4L2_MBUS_MASTER))
+               mt9v022->chip_control &= ~0x8;
+
+       ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
+       if (ret < 0)
+               return ret;
+
+       dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
+               pixclk, mt9v022->chip_control);
+
+       return 0;
+}
+
 static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
        .s_stream       = mt9v022_s_stream,
        .s_mbus_fmt     = mt9v022_s_fmt,
@@ -857,6 +754,8 @@ static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
        .g_crop         = mt9v022_g_crop,
        .cropcap        = mt9v022_cropcap,
        .enum_mbus_fmt  = mt9v022_enum_fmt,
+       .g_mbus_config  = mt9v022_g_mbus_config,
+       .s_mbus_config  = mt9v022_s_mbus_config,
 };
 
 static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
@@ -873,17 +772,10 @@ static int mt9v022_probe(struct i2c_client *client,
                         const struct i2c_device_id *did)
 {
        struct mt9v022 *mt9v022;
-       struct soc_camera_device *icd = client->dev.platform_data;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-       struct soc_camera_link *icl;
        int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
-               return -EINVAL;
-       }
-
-       icl = to_soc_camera_link(icd);
        if (!icl) {
                dev_err(&client->dev, "MT9V022 driver needs platform data\n");
                return -EINVAL;
@@ -900,10 +792,39 @@ static int mt9v022_probe(struct i2c_client *client,
                return -ENOMEM;
 
        v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
+       v4l2_ctrl_handler_init(&mt9v022->hdl, 6);
+       v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       mt9v022->autogain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
+       mt9v022->gain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_GAIN, 0, 127, 1, 64);
+
+       /*
+        * Simulated autoexposure. If enabled, we calculate shutter width
+        * ourselves in the driver based on vertical blanking and frame width
+        */
+       mt9v022->autoexposure = v4l2_ctrl_new_std_menu(&mt9v022->hdl,
+                       &mt9v022_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
+                       V4L2_EXPOSURE_AUTO);
+       mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
+                       V4L2_CID_EXPOSURE, 1, 255, 1, 255);
+
+       mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
+       if (mt9v022->hdl.error) {
+               int err = mt9v022->hdl.error;
+
+               kfree(mt9v022);
+               return err;
+       }
+       v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure,
+                               V4L2_EXPOSURE_MANUAL, true);
+       v4l2_ctrl_auto_cluster(2, &mt9v022->autogain, 0, true);
 
        mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
 
-       icd->ops                = &mt9v022_ops;
        /*
         * MT9V022 _really_ corrupts the first read out line.
         * TODO: verify on i.MX31
@@ -914,9 +835,9 @@ static int mt9v022_probe(struct i2c_client *client,
        mt9v022->rect.width     = MT9V022_MAX_WIDTH;
        mt9v022->rect.height    = MT9V022_MAX_HEIGHT;
 
-       ret = mt9v022_video_probe(icd, client);
+       ret = mt9v022_video_probe(client);
        if (ret) {
-               icd->ops = NULL;
+               v4l2_ctrl_handler_free(&mt9v022->hdl);
                kfree(mt9v022);
        }
 
@@ -926,10 +847,12 @@ static int mt9v022_probe(struct i2c_client *client,
 static int mt9v022_remove(struct i2c_client *client)
 {
        struct mt9v022 *mt9v022 = to_mt9v022(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
 
-       icd->ops = NULL;
-       mt9v022_video_remove(icd);
+       v4l2_device_unregister_subdev(&mt9v022->subdev);
+       if (icl->free_bus)
+               icl->free_bus(icl);
+       v4l2_ctrl_handler_free(&mt9v022->hdl);
        kfree(mt9v022);
 
        return 0;
index 087db12..18e94c7 100644 (file)
 #define CSI_IRQ_MASK   (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
                        CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
 
-#define CSI_BUS_FLAGS  (SOCAM_MASTER | SOCAM_HSYNC_ACTIVE_HIGH | \
-                       SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | \
-                       SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \
-                       SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW | \
-                       SOCAM_DATAWIDTH_8)
+#define CSI_BUS_FLAGS  (V4L2_MBUS_MASTER | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
+                       V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | \
+                       V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
+                       V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_LOW)
 
 #define MAX_VIDEO_MEM 16       /* Video memory limit in megabytes */
 
@@ -490,59 +489,73 @@ static int mx1_camera_set_crop(struct soc_camera_device *icd,
 
 static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 {
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct mx1_camera_dev *pcdev = ici->priv;
-       unsigned long camera_flags, common_flags;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long common_flags;
        unsigned int csicr1;
        int ret;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-
        /* MX1 supports only 8bit buswidth */
-       common_flags = soc_camera_bus_param_compatible(camera_flags,
-                                                      CSI_BUS_FLAGS);
-       if (!common_flags)
-               return -EINVAL;
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS);
+               if (!common_flags) {
+                       dev_warn(icd->parent,
+                                "Flags incompatible: camera 0x%x, host 0x%x\n",
+                                cfg.flags, CSI_BUS_FLAGS);
+                       return -EINVAL;
+               }
+       } else if (ret != -ENOIOCTLCMD) {
+               return ret;
+       } else {
+               common_flags = CSI_BUS_FLAGS;
+       }
 
        /* Make choises, based on platform choice */
-       if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
-               (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
+               (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
                        if (!pcdev->pdata ||
                             pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
-                               common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+                               common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
                        else
-                               common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+                               common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
        }
 
-       if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
-               (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+       if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
+               (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
                        if (!pcdev->pdata ||
                             pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
-                               common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+                               common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
                        else
-                               common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+                               common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
        }
 
-       if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) &&
-               (common_flags & SOCAM_DATA_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
+               (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
                        if (!pcdev->pdata ||
                             pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
-                               common_flags &= ~SOCAM_DATA_ACTIVE_LOW;
+                               common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
                        else
-                               common_flags &= ~SOCAM_DATA_ACTIVE_HIGH;
+                               common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
        }
 
-       ret = icd->ops->set_bus_param(icd, common_flags);
-       if (ret < 0)
+       cfg.flags = common_flags;
+       ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
+       if (ret < 0 && ret != -ENOIOCTLCMD) {
+               dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
+                       common_flags, ret);
                return ret;
+       }
 
        csicr1 = __raw_readl(pcdev->base + CSICR1);
 
-       if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
+       if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
                csicr1 |= CSICR1_REDGE;
-       if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
+       if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
                csicr1 |= CSICR1_SOF_POL;
-       if (common_flags & SOCAM_DATA_ACTIVE_LOW)
+       if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
                csicr1 |= CSICR1_DATA_POL;
 
        __raw_writel(csicr1, pcdev->base + CSICR1);
index ec2410c..a803d9e 100644 (file)
@@ -686,16 +686,15 @@ static void mx2_camera_init_videobuf(struct videobuf_queue *q,
                        icd, &icd->video_lock);
 }
 
-#define MX2_BUS_FLAGS  (SOCAM_DATAWIDTH_8 | \
-                       SOCAM_MASTER | \
-                       SOCAM_VSYNC_ACTIVE_HIGH | \
-                       SOCAM_VSYNC_ACTIVE_LOW | \
-                       SOCAM_HSYNC_ACTIVE_HIGH | \
-                       SOCAM_HSYNC_ACTIVE_LOW | \
-                       SOCAM_PCLK_SAMPLE_RISING | \
-                       SOCAM_PCLK_SAMPLE_FALLING | \
-                       SOCAM_DATA_ACTIVE_HIGH | \
-                       SOCAM_DATA_ACTIVE_LOW)
+#define MX2_BUS_FLAGS  (V4L2_MBUS_MASTER | \
+                       V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
+                       V4L2_MBUS_VSYNC_ACTIVE_LOW | \
+                       V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
+                       V4L2_MBUS_HSYNC_ACTIVE_LOW | \
+                       V4L2_MBUS_PCLK_SAMPLE_RISING | \
+                       V4L2_MBUS_PCLK_SAMPLE_FALLING | \
+                       V4L2_MBUS_DATA_ACTIVE_HIGH | \
+                       V4L2_MBUS_DATA_ACTIVE_LOW)
 
 static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev)
 {
@@ -770,46 +769,59 @@ static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
 static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
                __u32 pixfmt)
 {
-       struct soc_camera_host *ici =
-               to_soc_camera_host(icd->parent);
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct mx2_camera_dev *pcdev = ici->priv;
-       unsigned long camera_flags, common_flags;
-       int ret = 0;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long common_flags;
+       int ret;
        int bytesperline;
        u32 csicr1 = pcdev->csicr1;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-
-       common_flags = soc_camera_bus_param_compatible(camera_flags,
-                               MX2_BUS_FLAGS);
-       if (!common_flags)
-               return -EINVAL;
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg, MX2_BUS_FLAGS);
+               if (!common_flags) {
+                       dev_warn(icd->parent,
+                                "Flags incompatible: camera 0x%x, host 0x%x\n",
+                                cfg.flags, MX2_BUS_FLAGS);
+                       return -EINVAL;
+               }
+       } else if (ret != -ENOIOCTLCMD) {
+               return ret;
+       } else {
+               common_flags = MX2_BUS_FLAGS;
+       }
 
-       if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
                if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH)
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
                else
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
        }
 
-       if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
-           (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+       if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
+           (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
                if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING)
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
                else
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
        }
 
-       ret = icd->ops->set_bus_param(icd, common_flags);
-       if (ret < 0)
+       cfg.flags = common_flags;
+       ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
+       if (ret < 0 && ret != -ENOIOCTLCMD) {
+               dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
+                       common_flags, ret);
                return ret;
+       }
 
-       if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
+       if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
                csicr1 |= CSICR1_REDGE;
-       if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
+       if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
                csicr1 |= CSICR1_SOF_POL;
-       if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH)
+       if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
                csicr1 |= CSICR1_HSYNC_POL;
        if (pcdev->platform_flags & MX2_CAMERA_SWAP16)
                csicr1 |= CSICR1_SWAP16_EN;
index c8e958a..f96f92f 100644 (file)
@@ -109,10 +109,12 @@ struct mx3_camera_dev {
 
        unsigned long           platform_flags;
        unsigned long           mclk;
+       u16                     width_flags;    /* max 15 bits */
 
        struct list_head        capture;
        spinlock_t              lock;           /* Protects video buffer lists */
        struct mx3_camera_buffer *active;
+       size_t                  buf_total;
        struct vb2_alloc_ctx    *alloc_ctx;
        enum v4l2_field         field;
        int                     sequence;
@@ -190,79 +192,53 @@ static void mx3_cam_dma_done(void *arg)
  * Calculate the __buffer__ (not data) size and number of buffers.
  */
 static int mx3_videobuf_setup(struct vb2_queue *vq,
+                       const struct v4l2_format *fmt,
                        unsigned int *count, unsigned int *num_planes,
                        unsigned int sizes[], void *alloc_ctxs[])
 {
        struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct mx3_camera_dev *mx3_cam = ici->priv;
-       int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
-                                               icd->current_fmt->host_fmt);
-
-       if (bytes_per_line < 0)
-               return bytes_per_line;
+       int bytes_per_line;
+       unsigned int height;
 
        if (!mx3_cam->idmac_channel[0])
                return -EINVAL;
 
-       *num_planes = 1;
-
-       mx3_cam->sequence = 0;
-       sizes[0] = bytes_per_line * icd->user_height;
-       alloc_ctxs[0] = mx3_cam->alloc_ctx;
-
-       if (!*count)
-               *count = 32;
-
-       if (sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
-               *count = MAX_VIDEO_MEM * 1024 * 1024 / sizes[0];
-
-       return 0;
-}
-
-static int mx3_videobuf_prepare(struct vb2_buffer *vb)
-{
-       struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
-       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-       struct mx3_camera_dev *mx3_cam = ici->priv;
-       struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
-       struct scatterlist *sg;
-       struct mx3_camera_buffer *buf;
-       size_t new_size;
-       int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+       if (fmt) {
+               const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
+                                                               fmt->fmt.pix.pixelformat);
+               if (!xlate)
+                       return -EINVAL;
+               bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
+                                                        xlate->host_fmt);
+               height = fmt->fmt.pix.height;
+       } else {
+               /* Called from VIDIOC_REQBUFS or in compatibility mode */
+               bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
                                                icd->current_fmt->host_fmt);
-
+               height = icd->user_height;
+       }
        if (bytes_per_line < 0)
                return bytes_per_line;
 
-       buf = to_mx3_vb(vb);
-       sg = &buf->sg;
-
-       new_size = bytes_per_line * icd->user_height;
+       sizes[0] = bytes_per_line * height;
 
-       if (vb2_plane_size(vb, 0) < new_size) {
-               dev_err(icd->parent, "Buffer too small (%lu < %zu)\n",
-                       vb2_plane_size(vb, 0), new_size);
-               return -ENOBUFS;
-       }
+       alloc_ctxs[0] = mx3_cam->alloc_ctx;
 
-       if (buf->state == CSI_BUF_NEEDS_INIT) {
-               sg_dma_address(sg)      = vb2_dma_contig_plane_dma_addr(vb, 0);
-               sg_dma_len(sg)          = new_size;
+       if (!vq->num_buffers)
+               mx3_cam->sequence = 0;
 
-               buf->txd = ichan->dma_chan.device->device_prep_slave_sg(
-                       &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
-                       DMA_PREP_INTERRUPT);
-               if (!buf->txd)
-                       return -EIO;
-
-               buf->txd->callback_param        = buf->txd;
-               buf->txd->callback              = mx3_cam_dma_done;
+       if (!*count)
+               *count = 2;
 
-               buf->state = CSI_BUF_PREPARED;
-       }
+       /* If *num_planes != 0, we have already verified *count. */
+       if (!*num_planes &&
+           sizes[0] * *count + mx3_cam->buf_total > MAX_VIDEO_MEM * 1024 * 1024)
+               *count = (MAX_VIDEO_MEM * 1024 * 1024 - mx3_cam->buf_total) /
+                       sizes[0];
 
-       vb2_set_plane_payload(vb, 0, new_size);
+       *num_planes = 1;
 
        return 0;
 }
@@ -286,28 +262,58 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct mx3_camera_dev *mx3_cam = ici->priv;
        struct mx3_camera_buffer *buf = to_mx3_vb(vb);
-       struct dma_async_tx_descriptor *txd = buf->txd;
-       struct idmac_channel *ichan = to_idmac_chan(txd->chan);
+       struct scatterlist *sg = &buf->sg;
+       struct dma_async_tx_descriptor *txd;
+       struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
        struct idmac_video_param *video = &ichan->params.video;
-       dma_cookie_t cookie;
-       u32 fourcc = icd->current_fmt->host_fmt->fourcc;
+       const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt;
+       int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, host_fmt);
        unsigned long flags;
+       dma_cookie_t cookie;
+       size_t new_size;
+
+       BUG_ON(bytes_per_line <= 0);
+
+       new_size = bytes_per_line * icd->user_height;
+
+       if (vb2_plane_size(vb, 0) < new_size) {
+               dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
+                       vb->v4l2_buf.index, vb2_plane_size(vb, 0), new_size);
+               goto error;
+       }
+
+       if (buf->state == CSI_BUF_NEEDS_INIT) {
+               sg_dma_address(sg)      = vb2_dma_contig_plane_dma_addr(vb, 0);
+               sg_dma_len(sg)          = new_size;
+
+               txd = ichan->dma_chan.device->device_prep_slave_sg(
+                       &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
+                       DMA_PREP_INTERRUPT);
+               if (!txd)
+                       goto error;
+
+               txd->callback_param     = txd;
+               txd->callback           = mx3_cam_dma_done;
+
+               buf->state              = CSI_BUF_PREPARED;
+               buf->txd                = txd;
+       } else {
+               txd = buf->txd;
+       }
+
+       vb2_set_plane_payload(vb, 0, new_size);
 
        /* This is the configuration of one sg-element */
-       video->out_pixel_fmt    = fourcc_to_ipu_pix(fourcc);
+       video->out_pixel_fmt = fourcc_to_ipu_pix(host_fmt->fourcc);
 
        if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
                /*
-                * If the IPU DMA channel is configured to transport
-                * generic 8-bit data, we have to set up correctly the
-                * geometry parameters upon the current pixel format.
-                * So, since the DMA horizontal parameters are expressed
-                * in bytes not pixels, convert these in the right unit.
+                * If the IPU DMA channel is configured to transfer generic
+                * 8-bit data, we have to set up the geometry parameters
+                * correctly, according to the current pixel format. The DMA
+                * horizontal parameters in this case are expressed in bytes,
+                * not in pixels.
                 */
-               int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
-                                               icd->current_fmt->host_fmt);
-               BUG_ON(bytes_per_line <= 0);
-
                video->out_width        = bytes_per_line;
                video->out_height       = icd->user_height;
                video->out_stride       = bytes_per_line;
@@ -351,6 +357,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
                mx3_cam->active = NULL;
 
        spin_unlock_irqrestore(&mx3_cam->lock, flags);
+error:
        vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
 }
 
@@ -384,17 +391,24 @@ static void mx3_videobuf_release(struct vb2_buffer *vb)
        }
 
        spin_unlock_irqrestore(&mx3_cam->lock, flags);
+
+       mx3_cam->buf_total -= vb2_plane_size(vb, 0);
 }
 
 static int mx3_videobuf_init(struct vb2_buffer *vb)
 {
+       struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+       struct mx3_camera_dev *mx3_cam = ici->priv;
        struct mx3_camera_buffer *buf = to_mx3_vb(vb);
+
        /* This is for locking debugging only */
        INIT_LIST_HEAD(&buf->queue);
        sg_init_table(&buf->sg, 1);
 
        buf->state = CSI_BUF_NEEDS_INIT;
-       buf->txd = NULL;
+
+       mx3_cam->buf_total += vb2_plane_size(vb, 0);
 
        return 0;
 }
@@ -405,13 +419,12 @@ static int mx3_stop_streaming(struct vb2_queue *q)
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct mx3_camera_dev *mx3_cam = ici->priv;
        struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
-       struct dma_chan *chan;
        struct mx3_camera_buffer *buf, *tmp;
        unsigned long flags;
 
        if (ichan) {
-               chan = &ichan->dma_chan;
-               chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+               struct dma_chan *chan = &ichan->dma_chan;
+               chan->device->device_control(chan, DMA_PAUSE, 0);
        }
 
        spin_lock_irqsave(&mx3_cam->lock, flags);
@@ -419,8 +432,8 @@ static int mx3_stop_streaming(struct vb2_queue *q)
        mx3_cam->active = NULL;
 
        list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
-               buf->state = CSI_BUF_NEEDS_INIT;
                list_del_init(&buf->queue);
+               vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
        }
 
        spin_unlock_irqrestore(&mx3_cam->lock, flags);
@@ -430,7 +443,6 @@ static int mx3_stop_streaming(struct vb2_queue *q)
 
 static struct vb2_ops mx3_videobuf_ops = {
        .queue_setup    = mx3_videobuf_setup,
-       .buf_prepare    = mx3_videobuf_prepare,
        .buf_queue      = mx3_videobuf_queue,
        .buf_cleanup    = mx3_videobuf_release,
        .buf_init       = mx3_videobuf_init,
@@ -514,6 +526,7 @@ static int mx3_camera_add_device(struct soc_camera_device *icd)
 
        mx3_camera_activate(mx3_cam, icd);
 
+       mx3_cam->buf_total = 0;
        mx3_cam->icd = icd;
 
        dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
@@ -547,59 +560,28 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
 static int test_platform_param(struct mx3_camera_dev *mx3_cam,
                               unsigned char buswidth, unsigned long *flags)
 {
+       /*
+        * If requested data width is supported by the platform, use it or any
+        * possible lower value - i.MX31 is smart enough to shift bits
+        */
+       if (buswidth > fls(mx3_cam->width_flags))
+               return -EINVAL;
+
        /*
         * Platform specified synchronization and pixel clock polarities are
         * only a recommendation and are only used during probing. MX3x
         * camera interface only works in master mode, i.e., uses HSYNC and
         * VSYNC signals from the sensor
         */
-       *flags = SOCAM_MASTER |
-               SOCAM_HSYNC_ACTIVE_HIGH |
-               SOCAM_HSYNC_ACTIVE_LOW |
-               SOCAM_VSYNC_ACTIVE_HIGH |
-               SOCAM_VSYNC_ACTIVE_LOW |
-               SOCAM_PCLK_SAMPLE_RISING |
-               SOCAM_PCLK_SAMPLE_FALLING |
-               SOCAM_DATA_ACTIVE_HIGH |
-               SOCAM_DATA_ACTIVE_LOW;
-
-       /*
-        * If requested data width is supported by the platform, use it or any
-        * possible lower value - i.MX31 is smart enough to schift bits
-        */
-       if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
-               *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
-                       SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
-       else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
-               *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
-                       SOCAM_DATAWIDTH_4;
-       else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
-               *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
-       else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
-               *flags |= SOCAM_DATAWIDTH_4;
-
-       switch (buswidth) {
-       case 15:
-               if (!(*flags & SOCAM_DATAWIDTH_15))
-                       return -EINVAL;
-               break;
-       case 10:
-               if (!(*flags & SOCAM_DATAWIDTH_10))
-                       return -EINVAL;
-               break;
-       case 8:
-               if (!(*flags & SOCAM_DATAWIDTH_8))
-                       return -EINVAL;
-               break;
-       case 4:
-               if (!(*flags & SOCAM_DATAWIDTH_4))
-                       return -EINVAL;
-               break;
-       default:
-               dev_warn(mx3_cam->soc_host.v4l2_dev.dev,
-                        "Unsupported bus width %d\n", buswidth);
-               return -EINVAL;
-       }
+       *flags = V4L2_MBUS_MASTER |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_HSYNC_ACTIVE_LOW |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_VSYNC_ACTIVE_LOW |
+               V4L2_MBUS_PCLK_SAMPLE_RISING |
+               V4L2_MBUS_PCLK_SAMPLE_FALLING |
+               V4L2_MBUS_DATA_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_LOW;
 
        return 0;
 }
@@ -607,9 +589,11 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
 static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
                                    const unsigned int depth)
 {
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct mx3_camera_dev *mx3_cam = ici->priv;
-       unsigned long bus_flags, camera_flags;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long bus_flags, common_flags;
        int ret = test_platform_param(mx3_cam, depth, &bus_flags);
 
        dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret);
@@ -617,15 +601,21 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
        if (ret < 0)
                return ret;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-
-       ret = soc_camera_bus_param_compatible(camera_flags, bus_flags);
-       if (ret < 0)
-               dev_warn(icd->parent,
-                        "Flags incompatible: camera %lx, host %lx\n",
-                        camera_flags, bus_flags);
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg,
+                                                         bus_flags);
+               if (!common_flags) {
+                       dev_warn(icd->parent,
+                                "Flags incompatible: camera 0x%x, host 0x%lx\n",
+                                cfg.flags, bus_flags);
+                       return -EINVAL;
+               }
+       } else if (ret != -ENOIOCTLCMD) {
+               return ret;
+       }
 
-       return ret;
+       return 0;
 }
 
 static bool chan_filter(struct dma_chan *chan, void *arg)
@@ -994,9 +984,11 @@ static int mx3_camera_querycap(struct soc_camera_host *ici,
 
 static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 {
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct mx3_camera_dev *mx3_cam = ici->priv;
-       unsigned long bus_flags, camera_flags, common_flags;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long bus_flags, common_flags;
        u32 dw, sens_conf;
        const struct soc_mbus_pixelfmt *fmt;
        int buswidth;
@@ -1008,83 +1000,76 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
        if (!fmt)
                return -EINVAL;
 
-       buswidth = fmt->bits_per_sample;
-       ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
-
        xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
        if (!xlate) {
                dev_warn(dev, "Format %x not found\n", pixfmt);
                return -EINVAL;
        }
 
+       buswidth = fmt->bits_per_sample;
+       ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
+
        dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
 
        if (ret < 0)
                return ret;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-
-       common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
-       dev_dbg(dev, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n",
-               camera_flags, bus_flags, common_flags);
-       if (!common_flags) {
-               dev_dbg(dev, "no common flags");
-               return -EINVAL;
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg,
+                                                         bus_flags);
+               if (!common_flags) {
+                       dev_warn(icd->parent,
+                                "Flags incompatible: camera 0x%x, host 0x%lx\n",
+                                cfg.flags, bus_flags);
+                       return -EINVAL;
+               }
+       } else if (ret != -ENOIOCTLCMD) {
+               return ret;
+       } else {
+               common_flags = bus_flags;
        }
 
+       dev_dbg(dev, "Flags cam: 0x%x host: 0x%lx common: 0x%lx\n",
+               cfg.flags, bus_flags, common_flags);
+
        /* Make choices, based on platform preferences */
-       if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
                if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
                else
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
        }
 
-       if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
                if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
-                       common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
                else
-                       common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
        }
 
-       if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_DATA_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
                if (mx3_cam->platform_flags & MX3_CAMERA_DP)
-                       common_flags &= ~SOCAM_DATA_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
                else
-                       common_flags &= ~SOCAM_DATA_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
        }
 
-       if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
-           (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+       if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
+           (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
                if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
                else
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
        }
 
-       /*
-        * Make the camera work in widest common mode, we'll take care of
-        * the rest
-        */
-       if (common_flags & SOCAM_DATAWIDTH_15)
-               common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
-                       SOCAM_DATAWIDTH_15;
-       else if (common_flags & SOCAM_DATAWIDTH_10)
-               common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
-                       SOCAM_DATAWIDTH_10;
-       else if (common_flags & SOCAM_DATAWIDTH_8)
-               common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
-                       SOCAM_DATAWIDTH_8;
-       else
-               common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
-                       SOCAM_DATAWIDTH_4;
-
-       ret = icd->ops->set_bus_param(icd, common_flags);
-       if (ret < 0) {
-               dev_dbg(dev, "camera set_bus_param(%lx) returned %d\n",
+       cfg.flags = common_flags;
+       ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
+       if (ret < 0 && ret != -ENOIOCTLCMD) {
+               dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
                        common_flags, ret);
                return ret;
        }
@@ -1108,13 +1093,13 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
        /* This has been set in mx3_camera_activate(), but we clear it above */
        sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
 
-       if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
+       if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
                sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
-       if (common_flags & SOCAM_HSYNC_ACTIVE_LOW)
+       if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
                sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
-       if (common_flags & SOCAM_VSYNC_ACTIVE_LOW)
+       if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
                sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
-       if (common_flags & SOCAM_DATA_ACTIVE_LOW)
+       if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
                sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
 
        /* Just do what we're asked to do */
@@ -1199,6 +1184,14 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
                         "data widths, using default 8 bit\n");
                mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
        }
+       if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
+               mx3_cam->width_flags = 1 << 3;
+       if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
+               mx3_cam->width_flags |= 1 << 7;
+       if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
+               mx3_cam->width_flags |= 1 << 9;
+       if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
+               mx3_cam->width_flags |= 1 << 14;
 
        mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000;
        if (!mx3_cam->mclk) {
@@ -1281,8 +1274,6 @@ static int __devexit mx3_camera_remove(struct platform_device *pdev)
 
        dmaengine_put();
 
-       dev_info(&pdev->dev, "i.MX3x Camera driver unloaded\n");
-
        return 0;
 }
 
index 30d8896..9c5c19f 100644 (file)
@@ -833,6 +833,15 @@ static void omap_vout_buffer_release(struct videobuf_queue *q,
 /*
  *  File operations
  */
+static unsigned int omap_vout_poll(struct file *file,
+                                  struct poll_table_struct *wait)
+{
+       struct omap_vout_device *vout = file->private_data;
+       struct videobuf_queue *q = &vout->vbq;
+
+       return videobuf_poll_stream(file, q, wait);
+}
+
 static void omap_vout_vm_open(struct vm_area_struct *vma)
 {
        struct omap_vout_device *vout = vma->vm_private_data;
@@ -1861,6 +1870,7 @@ static const struct v4l2_ioctl_ops vout_ioctl_ops = {
 
 static const struct v4l2_file_operations omap_vout_fops = {
        .owner          = THIS_MODULE,
+       .poll           = omap_vout_poll,
        .unlocked_ioctl = video_ioctl2,
        .mmap           = omap_vout_mmap,
        .open           = omap_vout_open,
index 8a947e6..e87ae2f 100644 (file)
 /* end of OMAP1 Camera Interface registers */
 
 
-#define SOCAM_BUS_FLAGS        (SOCAM_MASTER | \
-                       SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | \
-                       SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \
-                       SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8)
+#define SOCAM_BUS_FLAGS        (V4L2_MBUS_MASTER | \
+                       V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
+                       V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
+                       V4L2_MBUS_DATA_ACTIVE_HIGH)
 
 
 #define FIFO_SIZE              ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1)
@@ -1438,41 +1438,55 @@ static int omap1_cam_querycap(struct soc_camera_host *ici,
 static int omap1_cam_set_bus_param(struct soc_camera_device *icd,
                __u32 pixfmt)
 {
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct device *dev = icd->parent;
        struct soc_camera_host *ici = to_soc_camera_host(dev);
        struct omap1_cam_dev *pcdev = ici->priv;
        const struct soc_camera_format_xlate *xlate;
        const struct soc_mbus_pixelfmt *fmt;
-       unsigned long camera_flags, common_flags;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long common_flags;
        u32 ctrlclock, mode;
        int ret;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-
-       common_flags = soc_camera_bus_param_compatible(camera_flags,
-                       SOCAM_BUS_FLAGS);
-       if (!common_flags)
-               return -EINVAL;
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg, SOCAM_BUS_FLAGS);
+               if (!common_flags) {
+                       dev_warn(dev,
+                                "Flags incompatible: camera 0x%x, host 0x%x\n",
+                                cfg.flags, SOCAM_BUS_FLAGS);
+                       return -EINVAL;
+               }
+       } else if (ret != -ENOIOCTLCMD) {
+               return ret;
+       } else {
+               common_flags = SOCAM_BUS_FLAGS;
+       }
 
        /* Make choices, possibly based on platform configuration */
-       if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
-                       (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+       if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
+                       (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
                if (!pcdev->pdata ||
                                pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING)
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
                else
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
        }
 
-       ret = icd->ops->set_bus_param(icd, common_flags);
-       if (ret < 0)
+       cfg.flags = common_flags;
+       ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
+       if (ret < 0 && ret != -ENOIOCTLCMD) {
+               dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
+                       common_flags, ret);
                return ret;
+       }
 
        ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
        if (ctrlclock & LCLK_EN)
                CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
 
-       if (common_flags & SOCAM_PCLK_SAMPLE_RISING) {
+       if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) {
                dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n");
                ctrlclock |= POLCLK;
        } else {
@@ -1565,10 +1579,10 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
        pcdev->clk = clk;
 
        pcdev->pdata = pdev->dev.platform_data;
-       pcdev->pflags = pcdev->pdata->flags;
-
-       if (pcdev->pdata)
+       if (pcdev->pdata) {
+               pcdev->pflags = pcdev->pdata->flags;
                pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000;
+       }
 
        switch (pcdev->camexclk) {
        case 6000000:
@@ -1578,6 +1592,7 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
        case 24000000:
                break;
        default:
+               /* pcdev->camexclk != 0 => pcdev->pdata != NULL */
                dev_warn(&pdev->dev,
                                "Incorrect sensor clock frequency %ld kHz, "
                                "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, "
@@ -1585,8 +1600,7 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
                                pcdev->pdata->camexclk_khz);
                pcdev->camexclk = 0;
        case 0:
-               dev_info(&pdev->dev,
-                               "Not providing sensor clock\n");
+               dev_info(&pdev->dev, "Not providing sensor clock\n");
        }
 
        INIT_LIST_HEAD(&pcdev->capture);
@@ -1716,5 +1730,5 @@ MODULE_PARM_DESC(sg_mode, "videobuf mode, 0: dma-contig (default), 1: dma-sg");
 MODULE_DESCRIPTION("OMAP1 Camera Interface driver");
 MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
 MODULE_LICENSE("GPL v2");
-MODULE_LICENSE(DRIVER_VERSION);
+MODULE_VERSION(DRIVER_VERSION);
 MODULE_ALIAS("platform:" DRIVER_NAME);
index 678e125..b818cac 100644 (file)
@@ -1704,6 +1704,7 @@ static int isp_register_entities(struct isp_device *isp)
        isp->media_dev.dev = isp->dev;
        strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
                sizeof(isp->media_dev.model));
+       isp->media_dev.hw_revision = isp->revision;
        isp->media_dev.link_notify = isp_pipeline_link_notify;
        ret = media_device_register(&isp->media_dev);
        if (ret < 0) {
@@ -2210,6 +2211,8 @@ error:
        regulator_put(isp->isp_csiphy2.vdd);
        regulator_put(isp->isp_csiphy1.vdd);
        platform_set_drvdata(pdev, NULL);
+
+       mutex_destroy(&isp->isp_mutex);
        kfree(isp);
 
        return ret;
index 253fdcc..b0b0fa5 100644 (file)
@@ -1836,7 +1836,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
                 * callers to request an output size bigger than the input size
                 * up to the nearest multiple of 16.
                 */
-               fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15);
+               fmt->width = clamp_t(u32, width, 32, fmt->width + 15);
                fmt->width &= ~15;
                fmt->height = clamp_t(u32, height, 32, fmt->height);
                break;
@@ -2152,6 +2152,37 @@ static const struct media_entity_operations ccdc_media_ops = {
        .link_setup = ccdc_link_setup,
 };
 
+void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
+{
+       v4l2_device_unregister_subdev(&ccdc->subdev);
+       omap3isp_video_unregister(&ccdc->video_out);
+}
+
+int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
+       struct v4l2_device *vdev)
+{
+       int ret;
+
+       /* Register the subdev and video node. */
+       ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
+       if (ret < 0)
+               goto error;
+
+       ret = omap3isp_video_register(&ccdc->video_out, vdev);
+       if (ret < 0)
+               goto error;
+
+       return 0;
+
+error:
+       omap3isp_ccdc_unregister_entities(ccdc);
+       return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * ISP CCDC initialisation and cleanup
+ */
+
 /*
  * ccdc_init_entities - Initialize V4L2 subdev and media entity
  * @ccdc: ISP CCDC module
@@ -2193,50 +2224,23 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 
        ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
        if (ret < 0)
-               return ret;
+               goto error_video;
 
        /* Connect the CCDC subdev to the video node. */
        ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
                        &ccdc->video_out.video.entity, 0, 0);
        if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
-{
-       media_entity_cleanup(&ccdc->subdev.entity);
-
-       v4l2_device_unregister_subdev(&ccdc->subdev);
-       omap3isp_video_unregister(&ccdc->video_out);
-}
-
-int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
-       struct v4l2_device *vdev)
-{
-       int ret;
-
-       /* Register the subdev and video node. */
-       ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
-       if (ret < 0)
-               goto error;
-
-       ret = omap3isp_video_register(&ccdc->video_out, vdev);
-       if (ret < 0)
-               goto error;
+               goto error_link;
 
        return 0;
 
-error:
-       omap3isp_ccdc_unregister_entities(ccdc);
+error_link:
+       omap3isp_video_cleanup(&ccdc->video_out);
+error_video:
+       media_entity_cleanup(me);
        return ret;
 }
 
-/* -----------------------------------------------------------------------------
- * ISP CCDC initialisation and cleanup
- */
-
 /*
  * omap3isp_ccdc_init - CCDC module initialization.
  * @dev: Device pointer specific to the OMAP3 ISP.
@@ -2248,6 +2252,7 @@ error:
 int omap3isp_ccdc_init(struct isp_device *isp)
 {
        struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
+       int ret;
 
        spin_lock_init(&ccdc->lock);
        init_waitqueue_head(&ccdc->wait);
@@ -2276,7 +2281,13 @@ int omap3isp_ccdc_init(struct isp_device *isp)
        ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
        ccdc_apply_controls(ccdc);
 
-       return ccdc_init_entities(ccdc);
+       ret = ccdc_init_entities(ccdc);
+       if (ret < 0) {
+               mutex_destroy(&ccdc->ioctl_lock);
+               return ret;
+       }
+
+       return 0;
 }
 
 /*
@@ -2287,6 +2298,9 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
 {
        struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
 
+       omap3isp_video_cleanup(&ccdc->video_out);
+       media_entity_cleanup(&ccdc->subdev.entity);
+
        /* Free LSC requests. As the CCDC is stopped there's no active request,
         * so only the pending request and the free queue need to be handled.
         */
@@ -2296,4 +2310,6 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
 
        if (ccdc->fpc.fpcaddr != 0)
                omap_iommu_vfree(isp->domain, isp->iommu, ccdc->fpc.fpcaddr);
+
+       mutex_destroy(&ccdc->ioctl_lock);
 }
index fa1d09b..904ca8c 100644 (file)
@@ -1031,6 +1031,48 @@ static const struct media_entity_operations ccp2_media_ops = {
        .link_setup = ccp2_link_setup,
 };
 
+/*
+ * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev
+ * @ccp2: Pointer to ISP CCP2 device
+ */
+void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
+{
+       v4l2_device_unregister_subdev(&ccp2->subdev);
+       omap3isp_video_unregister(&ccp2->video_in);
+}
+
+/*
+ * omap3isp_ccp2_register_entities - Register the subdev media entity
+ * @ccp2: Pointer to ISP CCP2 device
+ * @vdev: Pointer to v4l device
+ * return negative error code or zero on success
+ */
+
+int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
+                                   struct v4l2_device *vdev)
+{
+       int ret;
+
+       /* Register the subdev and video nodes. */
+       ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
+       if (ret < 0)
+               goto error;
+
+       ret = omap3isp_video_register(&ccp2->video_in, vdev);
+       if (ret < 0)
+               goto error;
+
+       return 0;
+
+error:
+       omap3isp_ccp2_unregister_entities(ccp2);
+       return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * ISP ccp2 initialisation and cleanup
+ */
+
 /*
  * ccp2_init_entities - Initialize ccp2 subdev and media entity.
  * @ccp2: Pointer to ISP CCP2 device
@@ -1083,72 +1125,23 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 
        ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
        if (ret < 0)
-               return ret;
+               goto error_video;
 
        /* Connect the video node to the ccp2 subdev. */
        ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
                                       &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
        if (ret < 0)
-               return ret;
+               goto error_link;
 
        return 0;
-}
 
-/*
- * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev
- * @ccp2: Pointer to ISP CCP2 device
- */
-void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
-{
+error_link:
+       omap3isp_video_cleanup(&ccp2->video_in);
+error_video:
        media_entity_cleanup(&ccp2->subdev.entity);
-
-       v4l2_device_unregister_subdev(&ccp2->subdev);
-       omap3isp_video_unregister(&ccp2->video_in);
-}
-
-/*
- * omap3isp_ccp2_register_entities - Register the subdev media entity
- * @ccp2: Pointer to ISP CCP2 device
- * @vdev: Pointer to v4l device
- * return negative error code or zero on success
- */
-
-int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
-                                   struct v4l2_device *vdev)
-{
-       int ret;
-
-       /* Register the subdev and video nodes. */
-       ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
-       if (ret < 0)
-               goto error;
-
-       ret = omap3isp_video_register(&ccp2->video_in, vdev);
-       if (ret < 0)
-               goto error;
-
-       return 0;
-
-error:
-       omap3isp_ccp2_unregister_entities(ccp2);
        return ret;
 }
 
-/* -----------------------------------------------------------------------------
- * ISP ccp2 initialisation and cleanup
- */
-
-/*
- * omap3isp_ccp2_cleanup - CCP2 un-initialization
- * @isp : Pointer to ISP device
- */
-void omap3isp_ccp2_cleanup(struct isp_device *isp)
-{
-       struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
-
-       regulator_put(ccp2->vdds_csib);
-}
-
 /*
  * omap3isp_ccp2_init - CCP2 initialization.
  * @isp : Pointer to ISP device
@@ -1184,13 +1177,25 @@ int omap3isp_ccp2_init(struct isp_device *isp)
        }
 
        ret = ccp2_init_entities(ccp2);
-       if (ret < 0)
-               goto out;
+       if (ret < 0) {
+               regulator_put(ccp2->vdds_csib);
+               return ret;
+       }
 
        ccp2_reset(ccp2);
-out:
-       if (ret)
-               omap3isp_ccp2_cleanup(isp);
+       return 0;
+}
 
-       return ret;
+/*
+ * omap3isp_ccp2_cleanup - CCP2 un-initialization
+ * @isp : Pointer to ISP device
+ */
+void omap3isp_ccp2_cleanup(struct isp_device *isp)
+{
+       struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
+
+       omap3isp_video_cleanup(&ccp2->video_in);
+       media_entity_cleanup(&ccp2->subdev.entity);
+
+       regulator_put(ccp2->vdds_csib);
 }
index 69161a6..0c5f1cb 100644 (file)
@@ -1187,6 +1187,37 @@ static const struct media_entity_operations csi2_media_ops = {
        .link_setup = csi2_link_setup,
 };
 
+void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
+{
+       v4l2_device_unregister_subdev(&csi2->subdev);
+       omap3isp_video_unregister(&csi2->video_out);
+}
+
+int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
+                                   struct v4l2_device *vdev)
+{
+       int ret;
+
+       /* Register the subdev and video nodes. */
+       ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
+       if (ret < 0)
+               goto error;
+
+       ret = omap3isp_video_register(&csi2->video_out, vdev);
+       if (ret < 0)
+               goto error;
+
+       return 0;
+
+error:
+       omap3isp_csi2_unregister_entities(csi2);
+       return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * ISP CSI2 initialisation and cleanup
+ */
+
 /*
  * csi2_init_entities - Initialize subdev and media entity.
  * @csi2: Pointer to csi2 structure.
@@ -1228,57 +1259,23 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 
        ret = omap3isp_video_init(&csi2->video_out, "CSI2a");
        if (ret < 0)
-               return ret;
+               goto error_video;
 
        /* Connect the CSI2 subdev to the video node. */
        ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
                                       &csi2->video_out.video.entity, 0, 0);
        if (ret < 0)
-               return ret;
+               goto error_link;
 
        return 0;
-}
 
-void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
-{
+error_link:
+       omap3isp_video_cleanup(&csi2->video_out);
+error_video:
        media_entity_cleanup(&csi2->subdev.entity);
-
-       v4l2_device_unregister_subdev(&csi2->subdev);
-       omap3isp_video_unregister(&csi2->video_out);
-}
-
-int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
-                                   struct v4l2_device *vdev)
-{
-       int ret;
-
-       /* Register the subdev and video nodes. */
-       ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
-       if (ret < 0)
-               goto error;
-
-       ret = omap3isp_video_register(&csi2->video_out, vdev);
-       if (ret < 0)
-               goto error;
-
-       return 0;
-
-error:
-       omap3isp_csi2_unregister_entities(csi2);
        return ret;
 }
 
-/* -----------------------------------------------------------------------------
- * ISP CSI2 initialisation and cleanup
- */
-
-/*
- * omap3isp_csi2_cleanup - Routine for module driver cleanup
- */
-void omap3isp_csi2_cleanup(struct isp_device *isp)
-{
-}
-
 /*
  * omap3isp_csi2_init - Routine for module driver init
  */
@@ -1298,7 +1295,7 @@ int omap3isp_csi2_init(struct isp_device *isp)
 
        ret = csi2_init_entities(csi2a);
        if (ret < 0)
-               goto fail;
+               return ret;
 
        if (isp->revision == ISP_REVISION_15_0) {
                csi2c->isp = isp;
@@ -1311,7 +1308,15 @@ int omap3isp_csi2_init(struct isp_device *isp)
        }
 
        return 0;
-fail:
-       omap3isp_csi2_cleanup(isp);
-       return ret;
+}
+
+/*
+ * omap3isp_csi2_cleanup - Routine for module driver cleanup
+ */
+void omap3isp_csi2_cleanup(struct isp_device *isp)
+{
+       struct isp_csi2_device *csi2a = &isp->isp_csi2a;
+
+       omap3isp_video_cleanup(&csi2a->video_out);
+       media_entity_cleanup(&csi2a->subdev.entity);
 }
index 8068cef..a3c76bf 100644 (file)
@@ -370,5 +370,5 @@ void omap3isp_h3a_aewb_cleanup(struct isp_device *isp)
 {
        kfree(isp->isp_aewb.priv);
        kfree(isp->isp_aewb.recover_priv);
-       omap3isp_stat_free(&isp->isp_aewb);
+       omap3isp_stat_cleanup(&isp->isp_aewb);
 }
index ba54d0a..58e0bc4 100644 (file)
@@ -425,5 +425,5 @@ void omap3isp_h3a_af_cleanup(struct isp_device *isp)
 {
        kfree(isp->isp_af.priv);
        kfree(isp->isp_af.recover_priv);
-       omap3isp_stat_free(&isp->isp_af);
+       omap3isp_stat_cleanup(&isp->isp_af);
 }
index 1743856..1163907 100644 (file)
@@ -516,5 +516,5 @@ void omap3isp_hist_cleanup(struct isp_device *isp)
        if (HIST_USING_DMA(&isp->isp_hist))
                omap_free_dma(isp->isp_hist.dma_ch);
        kfree(isp->isp_hist.priv);
-       omap3isp_stat_free(&isp->isp_hist);
+       omap3isp_stat_cleanup(&isp->isp_hist);
 }
index aba537a..ccb876f 100644 (file)
@@ -76,9 +76,51 @@ static struct omap3isp_prev_csc flr_prev_csc = {
 
 #define DEF_DETECT_CORRECT_VAL 0xe
 
-#define PREV_MIN_WIDTH         64
-#define PREV_MIN_HEIGHT                8
-#define PREV_MAX_HEIGHT                16384
+/*
+ * Margins and image size limits.
+ *
+ * The preview engine crops several rows and columns internally depending on
+ * which filters are enabled. To avoid format changes when the filters are
+ * enabled or disabled (which would prevent them from being turned on or off
+ * during streaming), the driver assumes all the filters are enabled when
+ * computing sink crop and source format limits.
+ *
+ * If a filter is disabled, additional cropping is automatically added at the
+ * preview engine input by the driver to avoid overflow at line and frame end.
+ * This is completely transparent for applications.
+ *
+ * Median filter               4 pixels
+ * Noise filter,
+ * Faulty pixels correction    4 pixels, 4 lines
+ * CFA filter                  4 pixels, 4 lines in Bayer mode
+ *                                       2 lines in other modes
+ * Color suppression           2 pixels
+ * or luma enhancement
+ * -------------------------------------------------------------
+ * Maximum total               14 pixels, 8 lines
+ *
+ * The color suppression and luma enhancement filters are applied after bayer to
+ * YUV conversion. They thus can crop one pixel on the left and one pixel on the
+ * right side of the image without changing the color pattern. When both those
+ * filters are disabled, the driver must crop the two pixels on the same side of
+ * the image to avoid changing the bayer pattern. The left margin is thus set to
+ * 8 pixels and the right margin to 6 pixels.
+ */
+
+#define PREV_MARGIN_LEFT       8
+#define PREV_MARGIN_RIGHT      6
+#define PREV_MARGIN_TOP                4
+#define PREV_MARGIN_BOTTOM     4
+
+#define PREV_MIN_IN_WIDTH      64
+#define PREV_MIN_IN_HEIGHT     8
+#define PREV_MAX_IN_HEIGHT     16384
+
+#define PREV_MIN_OUT_WIDTH     0
+#define PREV_MIN_OUT_HEIGHT    0
+#define PREV_MAX_OUT_WIDTH     1280
+#define PREV_MAX_OUT_WIDTH_ES2 3300
+#define PREV_MAX_OUT_WIDTH_3630        4096
 
 /*
  * Coeficient Tables for the submodules in Preview.
@@ -979,52 +1021,36 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average)
  * enabled when reporting source pad formats to userspace. If this assumption is
  * not true, rows and columns must be manually cropped at the preview engine
  * input to avoid overflows at the end of lines and frames.
+ *
+ * See the explanation at the PREV_MARGIN_* definitions for more details.
  */
 static void preview_config_input_size(struct isp_prev_device *prev)
 {
        struct isp_device *isp = to_isp_device(prev);
        struct prev_params *params = &prev->params;
-       struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK];
-       unsigned int sph = 0;
-       unsigned int eph = format->width - 1;
-       unsigned int slv = 0;
-       unsigned int elv = format->height - 1;
-
-       if (prev->input == PREVIEW_INPUT_CCDC) {
-               sph += 2;
-               eph -= 2;
+       unsigned int sph = prev->crop.left;
+       unsigned int eph = prev->crop.left + prev->crop.width - 1;
+       unsigned int slv = prev->crop.top;
+       unsigned int elv = prev->crop.top + prev->crop.height - 1;
+
+       if (params->features & PREV_CFA) {
+               sph -= 2;
+               eph += 2;
+               slv -= 2;
+               elv += 2;
        }
-
-       /*
-        * Median filter        4 pixels
-        * Noise filter         4 pixels, 4 lines
-        * or faulty pixels correction
-        * CFA filter           4 pixels, 4 lines in Bayer mode
-        *                                2 lines in other modes
-        * Color suppression    2 pixels
-        * or luma enhancement
-        * -------------------------------------------------------------
-        * Maximum total        14 pixels, 8 lines
-        */
-
-       if (!(params->features & PREV_CFA)) {
-               sph += 2;
-               eph -= 2;
-               slv += 2;
-               elv -= 2;
+       if (params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER)) {
+               sph -= 2;
+               eph += 2;
+               slv -= 2;
+               elv += 2;
        }
-       if (!(params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER))) {
-               sph += 2;
-               eph -= 2;
-               slv += 2;
-               elv -= 2;
+       if (params->features & PREV_HORZ_MEDIAN_FILTER) {
+               sph -= 2;
+               eph += 2;
        }
-       if (!(params->features & PREV_HORZ_MEDIAN_FILTER)) {
-               sph += 2;
-               eph -= 2;
-       }
-       if (!(params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE)))
-               sph += 2;
+       if (params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE))
+               sph -= 2;
 
        isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph,
                       OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO);
@@ -1228,7 +1254,6 @@ static void preview_init_params(struct isp_prev_device *prev)
        /* Init values */
        params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS;
        params->brightness = ISPPRV_BRIGHT_DEF * ISPPRV_BRIGHT_UNITS;
-       params->average = NO_AVE;
        params->cfa.format = OMAP3ISP_CFAFMT_BAYER;
        memcpy(params->cfa.table, cfa_coef_table,
               sizeof(params->cfa.table));
@@ -1281,14 +1306,14 @@ static unsigned int preview_max_out_width(struct isp_prev_device *prev)
 
        switch (isp->revision) {
        case ISP_REVISION_1_0:
-               return ISPPRV_MAXOUTPUT_WIDTH;
+               return PREV_MAX_OUT_WIDTH;
 
        case ISP_REVISION_2_0:
        default:
-               return ISPPRV_MAXOUTPUT_WIDTH_ES2;
+               return PREV_MAX_OUT_WIDTH_ES2;
 
        case ISP_REVISION_15_0:
-               return ISPPRV_MAXOUTPUT_WIDTH_3630;
+               return PREV_MAX_OUT_WIDTH_3630;
        }
 }
 
@@ -1296,8 +1321,6 @@ static void preview_configure(struct isp_prev_device *prev)
 {
        struct isp_device *isp = to_isp_device(prev);
        struct v4l2_mbus_framefmt *format;
-       unsigned int max_out_width;
-       unsigned int format_avg;
 
        preview_setup_hw(prev);
 
@@ -1335,10 +1358,7 @@ static void preview_configure(struct isp_prev_device *prev)
                preview_config_outlineoffset(prev,
                                ALIGN(format->width, 0x10) * 2);
 
-       max_out_width = preview_max_out_width(prev);
-
-       format_avg = fls(DIV_ROUND_UP(format->width, max_out_width) - 1);
-       preview_config_averager(prev, format_avg);
+       preview_config_averager(prev, 0);
        preview_config_ycpos(prev, format->code);
 }
 
@@ -1597,6 +1617,16 @@ __preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
                return &prev->formats[pad];
 }
 
+static struct v4l2_rect *
+__preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
+                  enum v4l2_subdev_format_whence which)
+{
+       if (which == V4L2_SUBDEV_FORMAT_TRY)
+               return v4l2_subdev_get_try_crop(fh, PREV_PAD_SINK);
+       else
+               return &prev->crop;
+}
+
 /* previewer format descriptions */
 static const unsigned int preview_input_fmts[] = {
        V4L2_MBUS_FMT_SGRBG10_1X10,
@@ -1611,24 +1641,25 @@ static const unsigned int preview_output_fmts[] = {
 };
 
 /*
- * preview_try_format - Handle try format by pad subdev method
- * @prev: ISP preview device
- * @fh : V4L2 subdev file handle
- * @pad: pad num
- * @fmt: pointer to v4l2 format structure
+ * preview_try_format - Validate a format
+ * @prev: ISP preview engine
+ * @fh: V4L2 subdev file handle
+ * @pad: pad number
+ * @fmt: format to be validated
+ * @which: try/active format selector
+ *
+ * Validate and adjust the given format for the given pad based on the preview
+ * engine limits and the format and crop rectangles on other pads.
  */
 static void preview_try_format(struct isp_prev_device *prev,
                               struct v4l2_subdev_fh *fh, unsigned int pad,
                               struct v4l2_mbus_framefmt *fmt,
                               enum v4l2_subdev_format_whence which)
 {
-       struct v4l2_mbus_framefmt *format;
-       unsigned int max_out_width;
        enum v4l2_mbus_pixelcode pixelcode;
+       struct v4l2_rect *crop;
        unsigned int i;
 
-       max_out_width = preview_max_out_width(prev);
-
        switch (pad) {
        case PREV_PAD_SINK:
                /* When reading data from the CCDC, the input size has already
@@ -1641,10 +1672,11 @@ static void preview_try_format(struct isp_prev_device *prev,
                 * filter array interpolation.
                 */
                if (prev->input == PREVIEW_INPUT_MEMORY) {
-                       fmt->width = clamp_t(u32, fmt->width, PREV_MIN_WIDTH,
-                                            max_out_width * 8);
-                       fmt->height = clamp_t(u32, fmt->height, PREV_MIN_HEIGHT,
-                                             PREV_MAX_HEIGHT);
+                       fmt->width = clamp_t(u32, fmt->width, PREV_MIN_IN_WIDTH,
+                                            preview_max_out_width(prev));
+                       fmt->height = clamp_t(u32, fmt->height,
+                                             PREV_MIN_IN_HEIGHT,
+                                             PREV_MAX_IN_HEIGHT);
                }
 
                fmt->colorspace = V4L2_COLORSPACE_SRGB;
@@ -1661,15 +1693,8 @@ static void preview_try_format(struct isp_prev_device *prev,
 
        case PREV_PAD_SOURCE:
                pixelcode = fmt->code;
-               format = __preview_get_format(prev, fh, PREV_PAD_SINK, which);
-               memcpy(fmt, format, sizeof(*fmt));
+               *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which);
 
-               /* The preview module output size is configurable through the
-                * input interface (horizontal and vertical cropping) and the
-                * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). In
-                * spite of this, hardcode the output size to the biggest
-                * possible value for simplicity reasons.
-                */
                switch (pixelcode) {
                case V4L2_MBUS_FMT_YUYV8_1X16:
                case V4L2_MBUS_FMT_UYVY8_1X16:
@@ -1681,31 +1706,14 @@ static void preview_try_format(struct isp_prev_device *prev,
                        break;
                }
 
-               /* The TRM states (12.1.4.7.1.2) that 2 pixels must be cropped
-                * from the left and right sides when the input source is the
-                * CCDC. This seems not to be needed in practice, investigation
-                * is required.
-                */
-               if (prev->input == PREVIEW_INPUT_CCDC)
-                       fmt->width -= 4;
-
-               /* The preview module can output a maximum of 3312 pixels
-                * horizontally due to fixed memory-line sizes. Compute the
-                * horizontal averaging factor accordingly. Note that the limit
-                * applies to the noise filter and CFA interpolation blocks, so
-                * it doesn't take cropping by further blocks into account.
-                *
-                * ES 1.0 hardware revision is limited to 1280 pixels
-                * horizontally.
-                */
-               fmt->width >>= fls(DIV_ROUND_UP(fmt->width, max_out_width) - 1);
-
-               /* Assume that all blocks are enabled and crop pixels and lines
-                * accordingly. See preview_config_input_size() for more
-                * information.
+               /* The preview module output size is configurable through the
+                * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). This
+                * is not supported yet, hardcode the output size to the crop
+                * rectangle size.
                 */
-               fmt->width -= 14;
-               fmt->height -= 8;
+               crop = __preview_get_crop(prev, fh, which);
+               fmt->width = crop->width;
+               fmt->height = crop->height;
 
                fmt->colorspace = V4L2_COLORSPACE_JPEG;
                break;
@@ -1714,6 +1722,49 @@ static void preview_try_format(struct isp_prev_device *prev,
        fmt->field = V4L2_FIELD_NONE;
 }
 
+/*
+ * preview_try_crop - Validate a crop rectangle
+ * @prev: ISP preview engine
+ * @sink: format on the sink pad
+ * @crop: crop rectangle to be validated
+ *
+ * The preview engine crops lines and columns for its internal operation,
+ * depending on which filters are enabled. Enforce minimum crop margins to
+ * handle that transparently for userspace.
+ *
+ * See the explanation at the PREV_MARGIN_* definitions for more details.
+ */
+static void preview_try_crop(struct isp_prev_device *prev,
+                            const struct v4l2_mbus_framefmt *sink,
+                            struct v4l2_rect *crop)
+{
+       unsigned int left = PREV_MARGIN_LEFT;
+       unsigned int right = sink->width - PREV_MARGIN_RIGHT;
+       unsigned int top = PREV_MARGIN_TOP;
+       unsigned int bottom = sink->height - PREV_MARGIN_BOTTOM;
+
+       /* When processing data on-the-fly from the CCDC, at least 2 pixels must
+        * be cropped from the left and right sides of the image. As we don't
+        * know which filters will be enabled, increase the left and right
+        * margins by two.
+        */
+       if (prev->input == PREVIEW_INPUT_CCDC) {
+               left += 2;
+               right -= 2;
+       }
+
+       /* Restrict left/top to even values to keep the Bayer pattern. */
+       crop->left &= ~1;
+       crop->top &= ~1;
+
+       crop->left = clamp_t(u32, crop->left, left, right - PREV_MIN_OUT_WIDTH);
+       crop->top = clamp_t(u32, crop->top, top, bottom - PREV_MIN_OUT_HEIGHT);
+       crop->width = clamp_t(u32, crop->width, PREV_MIN_OUT_WIDTH,
+                             right - crop->left);
+       crop->height = clamp_t(u32, crop->height, PREV_MIN_OUT_HEIGHT,
+                              bottom - crop->top);
+}
+
 /*
  * preview_enum_mbus_code - Handle pixel format enumeration
  * @sd     : pointer to v4l2 subdev structure
@@ -1775,6 +1826,60 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd,
        return 0;
 }
 
+/*
+ * preview_get_crop - Retrieve the crop rectangle on a pad
+ * @sd: ISP preview V4L2 subdevice
+ * @fh: V4L2 subdev file handle
+ * @crop: crop rectangle
+ *
+ * Return 0 on success or a negative error code otherwise.
+ */
+static int preview_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+                           struct v4l2_subdev_crop *crop)
+{
+       struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
+
+       /* Cropping is only supported on the sink pad. */
+       if (crop->pad != PREV_PAD_SINK)
+               return -EINVAL;
+
+       crop->rect = *__preview_get_crop(prev, fh, crop->which);
+       return 0;
+}
+
+/*
+ * preview_set_crop - Retrieve the crop rectangle on a pad
+ * @sd: ISP preview V4L2 subdevice
+ * @fh: V4L2 subdev file handle
+ * @crop: crop rectangle
+ *
+ * Return 0 on success or a negative error code otherwise.
+ */
+static int preview_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+                           struct v4l2_subdev_crop *crop)
+{
+       struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
+       struct v4l2_mbus_framefmt *format;
+
+       /* Cropping is only supported on the sink pad. */
+       if (crop->pad != PREV_PAD_SINK)
+               return -EINVAL;
+
+       /* The crop rectangle can't be changed while streaming. */
+       if (prev->state != ISP_PIPELINE_STREAM_STOPPED)
+               return -EBUSY;
+
+       format = __preview_get_format(prev, fh, PREV_PAD_SINK, crop->which);
+       preview_try_crop(prev, format, &crop->rect);
+       *__preview_get_crop(prev, fh, crop->which) = crop->rect;
+
+       /* Update the source format. */
+       format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, crop->which);
+       preview_try_format(prev, fh, PREV_PAD_SOURCE, format, crop->which);
+
+       return 0;
+}
+
 /*
  * preview_get_format - Handle get format by pads subdev method
  * @sd : pointer to v4l2 subdev structure
@@ -1808,6 +1913,7 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 {
        struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
        struct v4l2_mbus_framefmt *format;
+       struct v4l2_rect *crop;
 
        format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
        if (format == NULL)
@@ -1818,9 +1924,18 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 
        /* Propagate the format from sink to source */
        if (fmt->pad == PREV_PAD_SINK) {
+               /* Reset the crop rectangle. */
+               crop = __preview_get_crop(prev, fh, fmt->which);
+               crop->left = 0;
+               crop->top = 0;
+               crop->width = fmt->format.width;
+               crop->height = fmt->format.height;
+
+               preview_try_crop(prev, &fmt->format, crop);
+
+               /* Update the source format. */
                format = __preview_get_format(prev, fh, PREV_PAD_SOURCE,
                                              fmt->which);
-               *format = fmt->format;
                preview_try_format(prev, fh, PREV_PAD_SOURCE, format,
                                   fmt->which);
        }
@@ -1869,6 +1984,8 @@ static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops = {
        .enum_frame_size = preview_enum_frame_size,
        .get_fmt = preview_get_format,
        .set_fmt = preview_set_format,
+       .get_crop = preview_get_crop,
+       .set_crop = preview_set_crop,
 };
 
 /* subdev operations */
@@ -1966,8 +2083,44 @@ static const struct media_entity_operations preview_media_ops = {
        .link_setup = preview_link_setup,
 };
 
+void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
+{
+       v4l2_device_unregister_subdev(&prev->subdev);
+       omap3isp_video_unregister(&prev->video_in);
+       omap3isp_video_unregister(&prev->video_out);
+}
+
+int omap3isp_preview_register_entities(struct isp_prev_device *prev,
+       struct v4l2_device *vdev)
+{
+       int ret;
+
+       /* Register the subdev and video nodes. */
+       ret = v4l2_device_register_subdev(vdev, &prev->subdev);
+       if (ret < 0)
+               goto error;
+
+       ret = omap3isp_video_register(&prev->video_in, vdev);
+       if (ret < 0)
+               goto error;
+
+       ret = omap3isp_video_register(&prev->video_out, vdev);
+       if (ret < 0)
+               goto error;
+
+       return 0;
+
+error:
+       omap3isp_preview_unregister_entities(prev);
+       return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * ISP previewer initialisation and cleanup
+ */
+
 /*
- * review_init_entities - Initialize subdev and media entity.
+ * preview_init_entities - Initialize subdev and media entity.
  * @prev : Pointer to preview structure
  * return -ENOMEM or zero on success
  */
@@ -2024,69 +2177,34 @@ static int preview_init_entities(struct isp_prev_device *prev)
 
        ret = omap3isp_video_init(&prev->video_in, "preview");
        if (ret < 0)
-               return ret;
+               goto error_video_in;
 
        ret = omap3isp_video_init(&prev->video_out, "preview");
        if (ret < 0)
-               return ret;
+               goto error_video_out;
 
        /* Connect the video nodes to the previewer subdev. */
        ret = media_entity_create_link(&prev->video_in.video.entity, 0,
                        &prev->subdev.entity, PREV_PAD_SINK, 0);
        if (ret < 0)
-               return ret;
+               goto error_link;
 
        ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
                        &prev->video_out.video.entity, 0, 0);
        if (ret < 0)
-               return ret;
+               goto error_link;
 
        return 0;
-}
 
-void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
-{
+error_link:
+       omap3isp_video_cleanup(&prev->video_out);
+error_video_out:
+       omap3isp_video_cleanup(&prev->video_in);
+error_video_in:
        media_entity_cleanup(&prev->subdev.entity);
-
-       v4l2_device_unregister_subdev(&prev->subdev);
-       v4l2_ctrl_handler_free(&prev->ctrls);
-       omap3isp_video_unregister(&prev->video_in);
-       omap3isp_video_unregister(&prev->video_out);
-}
-
-int omap3isp_preview_register_entities(struct isp_prev_device *prev,
-       struct v4l2_device *vdev)
-{
-       int ret;
-
-       /* Register the subdev and video nodes. */
-       ret = v4l2_device_register_subdev(vdev, &prev->subdev);
-       if (ret < 0)
-               goto error;
-
-       ret = omap3isp_video_register(&prev->video_in, vdev);
-       if (ret < 0)
-               goto error;
-
-       ret = omap3isp_video_register(&prev->video_out, vdev);
-       if (ret < 0)
-               goto error;
-
-       return 0;
-
-error:
-       omap3isp_preview_unregister_entities(prev);
        return ret;
 }
 
-/* -----------------------------------------------------------------------------
- * ISP previewer initialisation and cleanup
- */
-
-void omap3isp_preview_cleanup(struct isp_device *isp)
-{
-}
-
 /*
  * isp_preview_init - Previewer initialization.
  * @dev : Pointer to ISP device
@@ -2095,19 +2213,20 @@ void omap3isp_preview_cleanup(struct isp_device *isp)
 int omap3isp_preview_init(struct isp_device *isp)
 {
        struct isp_prev_device *prev = &isp->isp_prev;
-       int ret;
 
        spin_lock_init(&prev->lock);
        init_waitqueue_head(&prev->wait);
        preview_init_params(prev);
 
-       ret = preview_init_entities(prev);
-       if (ret < 0)
-               goto out;
+       return preview_init_entities(prev);
+}
 
-out:
-       if (ret)
-               omap3isp_preview_cleanup(isp);
+void omap3isp_preview_cleanup(struct isp_device *isp)
+{
+       struct isp_prev_device *prev = &isp->isp_prev;
 
-       return ret;
+       v4l2_ctrl_handler_free(&prev->ctrls);
+       omap3isp_video_cleanup(&prev->video_in);
+       omap3isp_video_cleanup(&prev->video_out);
+       media_entity_cleanup(&prev->subdev.entity);
 }
index fa943bd..f54e775 100644 (file)
 #define ISPPRV_CONTRAST_HIGH           0xFF
 #define ISPPRV_CONTRAST_UNITS          0x1
 
-#define NO_AVE                         0x0
-#define AVE_2_PIX                      0x1
-#define AVE_4_PIX                      0x2
-#define AVE_8_PIX                      0x3
-
 /* Features list */
 #define PREV_LUMA_ENHANCE              OMAP3ISP_PREV_LUMAENH
 #define PREV_INVERSE_ALAW              OMAP3ISP_PREV_INVALAW
@@ -106,7 +101,6 @@ enum preview_ycpos_mode {
  * @rgb2ycbcr: RGB to ycbcr parameters.
  * @hmed: Horizontal median filter.
  * @yclimit: YC limits parameters.
- * @average: Downsampling rate for averager.
  * @contrast: Contrast.
  * @brightness: Brightness.
  */
@@ -124,7 +118,6 @@ struct prev_params {
        struct omap3isp_prev_csc rgb2ycbcr;
        struct omap3isp_prev_hmed hmed;
        struct omap3isp_prev_yclimit yclimit;
-       u8 average;
        u8 contrast;
        u8 brightness;
 };
@@ -159,6 +152,7 @@ struct isptables_update {
  * @subdev: V4L2 subdevice
  * @pads: Media entity pads
  * @formats: Active formats at the subdev pad
+ * @crop: Active crop rectangle
  * @input: Module currently connected to the input pad
  * @output: Bitmask of the active output
  * @video_in: Input video entity
@@ -177,6 +171,7 @@ struct isp_prev_device {
        struct v4l2_subdev subdev;
        struct media_pad pads[PREV_PADS_NUM];
        struct v4l2_mbus_framefmt formats[PREV_PADS_NUM];
+       struct v4l2_rect crop;
 
        struct v4l2_ctrl_handler ctrls;
 
index 69f6af6..084ea77 100644 (file)
 #define ISPPRV_YENH_TABLE_ADDR         0x1000
 #define ISPPRV_CFA_TABLE_ADDR          0x1400
 
-#define ISPPRV_MAXOUTPUT_WIDTH         1280
-#define ISPPRV_MAXOUTPUT_WIDTH_ES2     3300
-#define ISPPRV_MAXOUTPUT_WIDTH_3630    4096
 #define ISPRSZ_MIN_OUTPUT              64
 #define ISPRSZ_MAX_OUTPUT              3312
 
index 0bb0f8c..50e593b 100644 (file)
@@ -1608,6 +1608,42 @@ static const struct media_entity_operations resizer_media_ops = {
        .link_setup = resizer_link_setup,
 };
 
+void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
+{
+       v4l2_device_unregister_subdev(&res->subdev);
+       omap3isp_video_unregister(&res->video_in);
+       omap3isp_video_unregister(&res->video_out);
+}
+
+int omap3isp_resizer_register_entities(struct isp_res_device *res,
+                                      struct v4l2_device *vdev)
+{
+       int ret;
+
+       /* Register the subdev and video nodes. */
+       ret = v4l2_device_register_subdev(vdev, &res->subdev);
+       if (ret < 0)
+               goto error;
+
+       ret = omap3isp_video_register(&res->video_in, vdev);
+       if (ret < 0)
+               goto error;
+
+       ret = omap3isp_video_register(&res->video_out, vdev);
+       if (ret < 0)
+               goto error;
+
+       return 0;
+
+error:
+       omap3isp_resizer_unregister_entities(res);
+       return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * ISP resizer initialization and cleanup
+ */
+
 /*
  * resizer_init_entities - Initialize resizer subdev and media entity.
  * @res : Pointer to resizer device structure
@@ -1652,68 +1688,34 @@ static int resizer_init_entities(struct isp_res_device *res)
 
        ret = omap3isp_video_init(&res->video_in, "resizer");
        if (ret < 0)
-               return ret;
+               goto error_video_in;
 
        ret = omap3isp_video_init(&res->video_out, "resizer");
        if (ret < 0)
-               return ret;
+               goto error_video_out;
 
        /* Connect the video nodes to the resizer subdev. */
        ret = media_entity_create_link(&res->video_in.video.entity, 0,
                        &res->subdev.entity, RESZ_PAD_SINK, 0);
        if (ret < 0)
-               return ret;
+               goto error_link;
 
        ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
                        &res->video_out.video.entity, 0, 0);
        if (ret < 0)
-               return ret;
+               goto error_link;
 
        return 0;
-}
 
-void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
-{
+error_link:
+       omap3isp_video_cleanup(&res->video_out);
+error_video_out:
+       omap3isp_video_cleanup(&res->video_in);
+error_video_in:
        media_entity_cleanup(&res->subdev.entity);
-
-       v4l2_device_unregister_subdev(&res->subdev);
-       omap3isp_video_unregister(&res->video_in);
-       omap3isp_video_unregister(&res->video_out);
-}
-
-int omap3isp_resizer_register_entities(struct isp_res_device *res,
-                                      struct v4l2_device *vdev)
-{
-       int ret;
-
-       /* Register the subdev and video nodes. */
-       ret = v4l2_device_register_subdev(vdev, &res->subdev);
-       if (ret < 0)
-               goto error;
-
-       ret = omap3isp_video_register(&res->video_in, vdev);
-       if (ret < 0)
-               goto error;
-
-       ret = omap3isp_video_register(&res->video_out, vdev);
-       if (ret < 0)
-               goto error;
-
-       return 0;
-
-error:
-       omap3isp_resizer_unregister_entities(res);
        return ret;
 }
 
-/* -----------------------------------------------------------------------------
- * ISP resizer initialization and cleanup
- */
-
-void omap3isp_resizer_cleanup(struct isp_device *isp)
-{
-}
-
 /*
  * isp_resizer_init - Resizer initialization.
  * @isp : Pointer to ISP device
@@ -1722,17 +1724,17 @@ void omap3isp_resizer_cleanup(struct isp_device *isp)
 int omap3isp_resizer_init(struct isp_device *isp)
 {
        struct isp_res_device *res = &isp->isp_res;
-       int ret;
 
        init_waitqueue_head(&res->wait);
        atomic_set(&res->stopping, 0);
-       ret = resizer_init_entities(res);
-       if (ret < 0)
-               goto out;
+       return resizer_init_entities(res);
+}
 
-out:
-       if (ret)
-               omap3isp_resizer_cleanup(isp);
+void omap3isp_resizer_cleanup(struct isp_device *isp)
+{
+       struct isp_res_device *res = &isp->isp_res;
 
-       return ret;
+       omap3isp_video_cleanup(&res->video_in);
+       omap3isp_video_cleanup(&res->video_out);
+       media_entity_cleanup(&res->subdev.entity);
 }
index 7329055..68d5394 100644 (file)
@@ -1023,24 +1023,6 @@ void omap3isp_stat_dma_isr(struct ispstat *stat)
        __stat_isr(stat, 1);
 }
 
-static int isp_stat_init_entities(struct ispstat *stat, const char *name,
-                                 const struct v4l2_subdev_ops *sd_ops)
-{
-       struct v4l2_subdev *subdev = &stat->subdev;
-       struct media_entity *me = &subdev->entity;
-
-       v4l2_subdev_init(subdev, sd_ops);
-       snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
-       subdev->grp_id = 1 << 16;       /* group ID for isp subdevs */
-       subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
-       v4l2_set_subdevdata(subdev, stat);
-
-       stat->pad.flags = MEDIA_PAD_FL_SINK;
-       me->ops = NULL;
-
-       return media_entity_init(me, 1, &stat->pad, 0);
-}
-
 int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
                                  struct v4l2_fh *fh,
                                  struct v4l2_event_subscription *sub)
@@ -1062,7 +1044,6 @@ int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
 
 void omap3isp_stat_unregister_entities(struct ispstat *stat)
 {
-       media_entity_cleanup(&stat->subdev.entity);
        v4l2_device_unregister_subdev(&stat->subdev);
 }
 
@@ -1072,21 +1053,50 @@ int omap3isp_stat_register_entities(struct ispstat *stat,
        return v4l2_device_register_subdev(vdev, &stat->subdev);
 }
 
+static int isp_stat_init_entities(struct ispstat *stat, const char *name,
+                                 const struct v4l2_subdev_ops *sd_ops)
+{
+       struct v4l2_subdev *subdev = &stat->subdev;
+       struct media_entity *me = &subdev->entity;
+
+       v4l2_subdev_init(subdev, sd_ops);
+       snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
+       subdev->grp_id = 1 << 16;       /* group ID for isp subdevs */
+       subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
+       v4l2_set_subdevdata(subdev, stat);
+
+       stat->pad.flags = MEDIA_PAD_FL_SINK;
+       me->ops = NULL;
+
+       return media_entity_init(me, 1, &stat->pad, 0);
+}
+
 int omap3isp_stat_init(struct ispstat *stat, const char *name,
                       const struct v4l2_subdev_ops *sd_ops)
 {
+       int ret;
+
        stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL);
        if (!stat->buf)
                return -ENOMEM;
+
        isp_stat_buf_clear(stat);
        mutex_init(&stat->ioctl_lock);
        atomic_set(&stat->buf_err, 0);
 
-       return isp_stat_init_entities(stat, name, sd_ops);
+       ret = isp_stat_init_entities(stat, name, sd_ops);
+       if (ret < 0) {
+               mutex_destroy(&stat->ioctl_lock);
+               kfree(stat->buf);
+       }
+
+       return ret;
 }
 
-void omap3isp_stat_free(struct ispstat *stat)
+void omap3isp_stat_cleanup(struct ispstat *stat)
 {
+       media_entity_cleanup(&stat->subdev.entity);
+       mutex_destroy(&stat->ioctl_lock);
        isp_stat_bufs_free(stat);
        kfree(stat->buf);
 }
index d86da94..9b7c865 100644 (file)
@@ -144,7 +144,7 @@ int omap3isp_stat_request_statistics(struct ispstat *stat,
                                     struct omap3isp_stat_data *data);
 int omap3isp_stat_init(struct ispstat *stat, const char *name,
                       const struct v4l2_subdev_ops *sd_ops);
-void omap3isp_stat_free(struct ispstat *stat);
+void omap3isp_stat_cleanup(struct ispstat *stat);
 int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
                                  struct v4l2_fh *fh,
                                  struct v4l2_event_subscription *sub);
index 0cb8a9f..d100072 100644 (file)
@@ -1325,6 +1325,13 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
        return 0;
 }
 
+void omap3isp_video_cleanup(struct isp_video *video)
+{
+       media_entity_cleanup(&video->video.entity);
+       mutex_destroy(&video->stream_lock);
+       mutex_destroy(&video->mutex);
+}
+
 int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
 {
        int ret;
@@ -1341,8 +1348,6 @@ int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
 
 void omap3isp_video_unregister(struct isp_video *video)
 {
-       if (video_is_registered(&video->video)) {
-               media_entity_cleanup(&video->video.entity);
+       if (video_is_registered(&video->video))
                video_unregister_device(&video->video);
-       }
 }
index 53160aa..08cbfa1 100644 (file)
@@ -190,6 +190,7 @@ struct isp_video_fh {
                                container_of(q, struct isp_video_fh, queue)
 
 int omap3isp_video_init(struct isp_video *video, const char *name);
+void omap3isp_video_cleanup(struct isp_video *video);
 int omap3isp_video_register(struct isp_video *video,
                            struct v4l2_device *vdev);
 void omap3isp_video_unregister(struct isp_video *video);
index 9ce2fa0..b5247cb 100644 (file)
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
+
+#include <media/soc_camera.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-subdev.h>
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
+#include <media/v4l2-ctrls.h>
 
 #define VAL_SET(x, mask, rshift, lshift)  \
                ((((x) >> rshift) & mask) << lshift)
@@ -299,12 +301,10 @@ struct ov2640_win_size {
 
 struct ov2640_priv {
        struct v4l2_subdev              subdev;
-       struct ov2640_camera_info       *info;
+       struct v4l2_ctrl_handler        hdl;
        enum v4l2_mbus_pixelcode        cfmt_code;
        const struct ov2640_win_size    *win;
        int                             model;
-       u16                             flag_vflip:1;
-       u16                             flag_hflip:1;
 };
 
 /*
@@ -609,29 +609,6 @@ static enum v4l2_mbus_pixelcode ov2640_codes[] = {
        V4L2_MBUS_FMT_RGB565_2X8_LE,
 };
 
-/*
- * Supported controls
- */
-static const struct v4l2_queryctrl ov2640_controls[] = {
-       {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Vertically",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       }, {
-               .id             = V4L2_CID_HFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Horizontally",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-};
-
 /*
  * General functions
  */
@@ -701,81 +678,23 @@ static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
        return 0;
 }
 
-static int ov2640_set_bus_param(struct soc_camera_device *icd,
-                               unsigned long flags)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
-
-       /* Only one width bit may be set */
-       if (!is_power_of_2(width_flag))
-               return -EINVAL;
-
-       if (icl->set_bus_param)
-               return icl->set_bus_param(icl, width_flag);
-
-       /*
-        * Without board specific bus width settings we support only the
-        * sensors native bus width witch are tested working
-        */
-       if (width_flag & (SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8))
-               return 0;
-
-       return 0;
-}
-
-static unsigned long ov2640_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
-               SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
-               SOCAM_DATA_ACTIVE_HIGH;
-
-       if (icl->query_bus_param)
-               flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
-       else
-               flags |= SOCAM_DATAWIDTH_10;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
-static int ov2640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+       struct v4l2_subdev *sd =
+               &container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev;
        struct i2c_client  *client = v4l2_get_subdevdata(sd);
-       struct ov2640_priv *priv = to_ov2640(client);
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               ctrl->value = priv->flag_vflip;
-               break;
-       case V4L2_CID_HFLIP:
-               ctrl->value = priv->flag_hflip;
-               break;
-       }
-       return 0;
-}
-
-static int ov2640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-       struct i2c_client  *client = v4l2_get_subdevdata(sd);
-       struct ov2640_priv *priv = to_ov2640(client);
-       int ret = 0;
        u8 val;
 
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               val = ctrl->value ? REG04_VFLIP_IMG : 0x00;
-               priv->flag_vflip = ctrl->value ? 1 : 0;
-               ret = ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
-               break;
+               val = ctrl->val ? REG04_VFLIP_IMG : 0x00;
+               return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
        case V4L2_CID_HFLIP:
-               val = ctrl->value ? REG04_HFLIP_IMG : 0x00;
-               priv->flag_hflip = ctrl->value ? 1 : 0;
-               ret = ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
-               break;
+               val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
+               return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
        }
 
-       return ret;
+       return -EINVAL;
 }
 
 static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
@@ -1023,18 +942,13 @@ static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
        return 0;
 }
 
-static int ov2640_video_probe(struct soc_camera_device *icd,
-                             struct i2c_client *client)
+static int ov2640_video_probe(struct i2c_client *client)
 {
        struct ov2640_priv *priv = to_ov2640(client);
        u8 pid, ver, midh, midl;
        const char *devname;
        int ret;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
        /*
         * check and show product ID and manufacturer ID
         */
@@ -1060,22 +974,17 @@ static int ov2640_video_probe(struct soc_camera_device *icd,
                 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
                 devname, pid, ver, midh, midl);
 
-       return 0;
+       return v4l2_ctrl_handler_setup(&priv->hdl);
 
 err:
        return ret;
 }
 
-static struct soc_camera_ops ov2640_ops = {
-       .set_bus_param          = ov2640_set_bus_param,
-       .query_bus_param        = ov2640_query_bus_param,
-       .controls               = ov2640_controls,
-       .num_controls           = ARRAY_SIZE(ov2640_controls),
+static const struct v4l2_ctrl_ops ov2640_ctrl_ops = {
+       .s_ctrl = ov2640_s_ctrl,
 };
 
 static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
-       .g_ctrl         = ov2640_g_ctrl,
-       .s_ctrl         = ov2640_s_ctrl,
        .g_chip_ident   = ov2640_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register     = ov2640_g_register,
@@ -1083,6 +992,21 @@ static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
 #endif
 };
 
+static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
 static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
        .s_stream       = ov2640_s_stream,
        .g_mbus_fmt     = ov2640_g_fmt,
@@ -1091,6 +1015,7 @@ static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
        .cropcap        = ov2640_cropcap,
        .g_crop         = ov2640_g_crop,
        .enum_mbus_fmt  = ov2640_enum_fmt,
+       .g_mbus_config  = ov2640_g_mbus_config,
 };
 
 static struct v4l2_subdev_ops ov2640_subdev_ops = {
@@ -1104,18 +1029,11 @@ static struct v4l2_subdev_ops ov2640_subdev_ops = {
 static int ov2640_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 {
-       struct ov2640_priv        *priv;
-       struct soc_camera_device  *icd = client->dev.platform_data;
-       struct i2c_adapter        *adapter = to_i2c_adapter(client->dev.parent);
-       struct soc_camera_link    *icl;
-       int                        ret;
-
-       if (!icd) {
-               dev_err(&adapter->dev, "OV2640: missing soc-camera data!\n");
-               return -EINVAL;
-       }
+       struct ov2640_priv      *priv;
+       struct soc_camera_link  *icl = soc_camera_i2c_to_link(client);
+       struct i2c_adapter      *adapter = to_i2c_adapter(client->dev.parent);
+       int                     ret;
 
-       icl = to_soc_camera_link(icd);
        if (!icl) {
                dev_err(&adapter->dev,
                        "OV2640: Missing platform_data for driver\n");
@@ -1135,15 +1053,23 @@ static int ov2640_probe(struct i2c_client *client,
                return -ENOMEM;
        }
 
-       priv->info = icl->priv;
-
        v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
+       v4l2_ctrl_handler_init(&priv->hdl, 2);
+       v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       priv->subdev.ctrl_handler = &priv->hdl;
+       if (priv->hdl.error) {
+               int err = priv->hdl.error;
 
-       icd->ops = &ov2640_ops;
+               kfree(priv);
+               return err;
+       }
 
-       ret = ov2640_video_probe(icd, client);
+       ret = ov2640_video_probe(client);
        if (ret) {
-               icd->ops = NULL;
+               v4l2_ctrl_handler_free(&priv->hdl);
                kfree(priv);
        } else {
                dev_info(&adapter->dev, "OV2640 Probed\n");
@@ -1155,9 +1081,9 @@ static int ov2640_probe(struct i2c_client *client,
 static int ov2640_remove(struct i2c_client *client)
 {
        struct ov2640_priv       *priv = to_ov2640(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
 
-       icd->ops = NULL;
+       v4l2_device_unregister_subdev(&priv->subdev);
+       v4l2_ctrl_handler_free(&priv->hdl);
        kfree(priv);
        return 0;
 }
index 349a4ad..bb37ec8 100644 (file)
  * published by the Free Software Foundation.
  */
 
+#include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
+#include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/module.h>
+#include <linux/v4l2-mediabus.h>
 
 #include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-subdev.h>
 
@@ -35,7 +37,7 @@
 #define REG_WINDOW_START_Y_LOW         0x3803
 #define REG_WINDOW_WIDTH_HIGH          0x3804
 #define REG_WINDOW_WIDTH_LOW           0x3805
-#define REG_WINDOW_HEIGHT_HIGH                 0x3806
+#define REG_WINDOW_HEIGHT_HIGH         0x3806
 #define REG_WINDOW_HEIGHT_LOW          0x3807
 #define REG_OUT_WIDTH_HIGH             0x3808
 #define REG_OUT_WIDTH_LOW              0x3809
 #define REG_OUT_TOTAL_WIDTH_LOW                0x380d
 #define REG_OUT_TOTAL_HEIGHT_HIGH      0x380e
 #define REG_OUT_TOTAL_HEIGHT_LOW       0x380f
+#define REG_OUTPUT_FORMAT              0x4300
+#define REG_ISP_CTRL_01                        0x5001
+#define REG_AVG_WINDOW_END_X_HIGH      0x5682
+#define REG_AVG_WINDOW_END_X_LOW       0x5683
+#define REG_AVG_WINDOW_END_Y_HIGH      0x5686
+#define REG_AVG_WINDOW_END_Y_LOW       0x5687
+
+/* active pixel array size */
+#define OV5642_SENSOR_SIZE_X   2592
+#define OV5642_SENSOR_SIZE_Y   1944
 
 /*
- * define standard resolution.
- * Works currently only for up to 720 lines
- * eg. 320x240, 640x480, 800x600, 1280x720, 2048x720
+ * About OV5642 resolution, cropping and binning:
+ * This sensor supports it all, at least in the feature description.
+ * Unfortunately, no combination of appropriate registers settings could make
+ * the chip work the intended way. As it works with predefined register lists,
+ * some undocumented registers are presumably changed there to achieve their
+ * goals.
+ * This driver currently only works for resolutions up to 720 lines with a
+ * 1:1 scale. Hopefully these restrictions will be removed in the future.
  */
+#define OV5642_MAX_WIDTH       OV5642_SENSOR_SIZE_X
+#define OV5642_MAX_HEIGHT      720
 
-#define OV5642_WIDTH           1280
-#define OV5642_HEIGHT          720
-#define OV5642_TOTAL_WIDTH     3200
-#define OV5642_TOTAL_HEIGHT    2000
-#define OV5642_SENSOR_SIZE_X   2592
-#define OV5642_SENSOR_SIZE_Y   1944
+/* default sizes */
+#define OV5642_DEFAULT_WIDTH   1280
+#define OV5642_DEFAULT_HEIGHT  OV5642_MAX_HEIGHT
+
+/* minimum extra blanking */
+#define BLANKING_EXTRA_WIDTH           500
+#define BLANKING_EXTRA_HEIGHT          20
+
+/*
+ * the sensor's autoexposure is buggy when setting total_height low.
+ * It tries to expose longer than 1 frame period without taking care of it
+ * and this leads to weird output. So we set 1000 lines as minimum.
+ */
+#define BLANKING_MIN_HEIGHT            1000
 
 struct regval_list {
        u16 reg_num;
@@ -582,6 +609,11 @@ struct ov5642_datafmt {
 struct ov5642 {
        struct v4l2_subdev              subdev;
        const struct ov5642_datafmt     *fmt;
+       struct v4l2_rect                crop_rect;
+
+       /* blanking information */
+       int total_width;
+       int total_height;
 };
 
 static const struct ov5642_datafmt ov5642_colour_fmts[] = {
@@ -642,6 +674,21 @@ static int reg_write(struct i2c_client *client, u16 reg, u8 val)
 
        return 0;
 }
+
+/*
+ * convenience function to write 16 bit register values that are split up
+ * into two consecutive high and low parts
+ */
+static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
+{
+       int ret;
+
+       ret = reg_write(client, reg, val16 >> 8);
+       if (ret)
+               return ret;
+       return reg_write(client, reg + 1, val16 & 0x00ff);
+}
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
@@ -685,58 +732,55 @@ static int ov5642_write_array(struct i2c_client *client,
        return 0;
 }
 
-static int ov5642_set_resolution(struct i2c_client *client)
+static int ov5642_set_resolution(struct v4l2_subdev *sd)
 {
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov5642 *priv = to_ov5642(client);
+       int width = priv->crop_rect.width;
+       int height = priv->crop_rect.height;
+       int total_width = priv->total_width;
+       int total_height = priv->total_height;
+       int start_x = (OV5642_SENSOR_SIZE_X - width) / 2;
+       int start_y = (OV5642_SENSOR_SIZE_Y - height) / 2;
        int ret;
-       u8 start_x_high = ((OV5642_SENSOR_SIZE_X - OV5642_WIDTH) / 2) >> 8;
-       u8 start_x_low  = ((OV5642_SENSOR_SIZE_X - OV5642_WIDTH) / 2) & 0xff;
-       u8 start_y_high = ((OV5642_SENSOR_SIZE_Y - OV5642_HEIGHT) / 2) >> 8;
-       u8 start_y_low  = ((OV5642_SENSOR_SIZE_Y - OV5642_HEIGHT) / 2) & 0xff;
-
-       u8 width_high   = OV5642_WIDTH  >> 8;
-       u8 width_low    = OV5642_WIDTH  & 0xff;
-       u8 height_high  = OV5642_HEIGHT >> 8;
-       u8 height_low   = OV5642_HEIGHT & 0xff;
-
-       u8 total_width_high  = OV5642_TOTAL_WIDTH  >> 8;
-       u8 total_width_low   = OV5642_TOTAL_WIDTH  & 0xff;
-       u8 total_height_high = OV5642_TOTAL_HEIGHT >> 8;
-       u8 total_height_low  = OV5642_TOTAL_HEIGHT & 0xff;
-
-       ret = reg_write(client, REG_WINDOW_START_X_HIGH, start_x_high);
-       if (!ret)
-               ret = reg_write(client, REG_WINDOW_START_X_LOW, start_x_low);
-       if (!ret)
-               ret = reg_write(client, REG_WINDOW_START_Y_HIGH, start_y_high);
-       if (!ret)
-               ret = reg_write(client, REG_WINDOW_START_Y_LOW, start_y_low);
 
+       /*
+        * This should set the starting point for cropping.
+        * Doesn't work so far.
+        */
+       ret = reg_write16(client, REG_WINDOW_START_X_HIGH, start_x);
        if (!ret)
-               ret = reg_write(client, REG_WINDOW_WIDTH_HIGH, width_high);
-       if (!ret)
-               ret = reg_write(client, REG_WINDOW_WIDTH_LOW , width_low);
-       if (!ret)
-               ret = reg_write(client, REG_WINDOW_HEIGHT_HIGH, height_high);
-       if (!ret)
-               ret = reg_write(client, REG_WINDOW_HEIGHT_LOW,  height_low);
+               ret = reg_write16(client, REG_WINDOW_START_Y_HIGH, start_y);
+       if (!ret) {
+               priv->crop_rect.left = start_x;
+               priv->crop_rect.top = start_y;
+       }
 
        if (!ret)
-               ret = reg_write(client, REG_OUT_WIDTH_HIGH, width_high);
+               ret = reg_write16(client, REG_WINDOW_WIDTH_HIGH, width);
        if (!ret)
-               ret = reg_write(client, REG_OUT_WIDTH_LOW , width_low);
-       if (!ret)
-               ret = reg_write(client, REG_OUT_HEIGHT_HIGH, height_high);
+               ret = reg_write16(client, REG_WINDOW_HEIGHT_HIGH, height);
+       if (ret)
+               return ret;
+       priv->crop_rect.width = width;
+       priv->crop_rect.height = height;
+
+       /* Set the output window size. Only 1:1 scale is supported so far. */
+       ret = reg_write16(client, REG_OUT_WIDTH_HIGH, width);
        if (!ret)
-               ret = reg_write(client, REG_OUT_HEIGHT_LOW,  height_low);
+               ret = reg_write16(client, REG_OUT_HEIGHT_HIGH, height);
 
+       /* Total width = output size + blanking */
        if (!ret)
-               ret = reg_write(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width_high);
+               ret = reg_write16(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width);
        if (!ret)
-               ret = reg_write(client, REG_OUT_TOTAL_WIDTH_LOW, total_width_low);
+               ret = reg_write16(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height);
+
+       /* Sets the window for AWB calculations */
        if (!ret)
-               ret = reg_write(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height_high);
+               ret = reg_write16(client, REG_AVG_WINDOW_END_X_HIGH, width);
        if (!ret)
-               ret = reg_write(client, REG_OUT_TOTAL_HEIGHT_LOW,  total_height_low);
+               ret = reg_write16(client, REG_AVG_WINDOW_END_Y_HIGH, height);
 
        return ret;
 }
@@ -744,18 +788,18 @@ static int ov5642_set_resolution(struct i2c_client *client)
 static int ov5642_try_fmt(struct v4l2_subdev *sd,
                          struct v4l2_mbus_framefmt *mf)
 {
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov5642 *priv = to_ov5642(client);
        const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code);
 
-       dev_dbg(sd->v4l2_dev->dev, "%s(%u) width: %u heigth: %u\n",
-                       __func__, mf->code, mf->width, mf->height);
+       mf->width = priv->crop_rect.width;
+       mf->height = priv->crop_rect.height;
 
        if (!fmt) {
                mf->code        = ov5642_colour_fmts[0].code;
                mf->colorspace  = ov5642_colour_fmts[0].colorspace;
        }
 
-       mf->width       = OV5642_WIDTH;
-       mf->height      = OV5642_HEIGHT;
        mf->field       = V4L2_FIELD_NONE;
 
        return 0;
@@ -767,20 +811,13 @@ static int ov5642_s_fmt(struct v4l2_subdev *sd,
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct ov5642 *priv = to_ov5642(client);
 
-       dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code);
-
        /* MIPI CSI could have changed the format, double-check */
        if (!ov5642_find_datafmt(mf->code))
                return -EINVAL;
 
        ov5642_try_fmt(sd, mf);
-
        priv->fmt = ov5642_find_datafmt(mf->code);
 
-       ov5642_write_array(client, ov5642_default_regs_init);
-       ov5642_set_resolution(client);
-       ov5642_write_array(client, ov5642_default_regs_finalise);
-
        return 0;
 }
 
@@ -794,8 +831,8 @@ static int ov5642_g_fmt(struct v4l2_subdev *sd,
 
        mf->code        = fmt->code;
        mf->colorspace  = fmt->colorspace;
-       mf->width       = OV5642_WIDTH;
-       mf->height      = OV5642_HEIGHT;
+       mf->width       = priv->crop_rect.width;
+       mf->height      = priv->crop_rect.height;
        mf->field       = V4L2_FIELD_NONE;
 
        return 0;
@@ -828,15 +865,44 @@ static int ov5642_g_chip_ident(struct v4l2_subdev *sd,
        return 0;
 }
 
+static int ov5642_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov5642 *priv = to_ov5642(client);
+       struct v4l2_rect *rect = &a->c;
+       int ret;
+
+       v4l_bound_align_image(&rect->width, 48, OV5642_MAX_WIDTH, 1,
+                             &rect->height, 32, OV5642_MAX_HEIGHT, 1, 0);
+
+       priv->crop_rect.width   = rect->width;
+       priv->crop_rect.height  = rect->height;
+       priv->total_width       = rect->width + BLANKING_EXTRA_WIDTH;
+       priv->total_height      = max_t(int, rect->height +
+                                                       BLANKING_EXTRA_HEIGHT,
+                                                       BLANKING_MIN_HEIGHT);
+       priv->crop_rect.width           = rect->width;
+       priv->crop_rect.height          = rect->height;
+
+       ret = ov5642_write_array(client, ov5642_default_regs_init);
+       if (!ret)
+               ret = ov5642_set_resolution(sd);
+       if (!ret)
+               ret = ov5642_write_array(client, ov5642_default_regs_finalise);
+
+       return ret;
+}
+
 static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov5642 *priv = to_ov5642(client);
        struct v4l2_rect *rect = &a->c;
 
-       a->type         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       rect->top       = 0;
-       rect->left      = 0;
-       rect->width     = OV5642_WIDTH;
-       rect->height    = OV5642_HEIGHT;
+       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       *rect = priv->crop_rect;
 
        return 0;
 }
@@ -845,8 +911,8 @@ static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 {
        a->bounds.left                  = 0;
        a->bounds.top                   = 0;
-       a->bounds.width                 = OV5642_WIDTH;
-       a->bounds.height                = OV5642_HEIGHT;
+       a->bounds.width                 = OV5642_MAX_WIDTH;
+       a->bounds.height                = OV5642_MAX_HEIGHT;
        a->defrect                      = a->bounds;
        a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        a->pixelaspect.numerator        = 1;
@@ -855,16 +921,47 @@ static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
        return 0;
 }
 
+static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       cfg->type = V4L2_MBUS_CSI2;
+       cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
+                                       V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+
+       return 0;
+}
+
+static int ov5642_s_power(struct v4l2_subdev *sd, int on)
+{
+       struct i2c_client *client;
+       int ret;
+
+       if (!on)
+               return 0;
+
+       client = v4l2_get_subdevdata(sd);
+       ret = ov5642_write_array(client, ov5642_default_regs_init);
+       if (!ret)
+               ret = ov5642_set_resolution(sd);
+       if (!ret)
+               ret = ov5642_write_array(client, ov5642_default_regs_finalise);
+
+       return ret;
+}
+
 static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
        .s_mbus_fmt     = ov5642_s_fmt,
        .g_mbus_fmt     = ov5642_g_fmt,
        .try_mbus_fmt   = ov5642_try_fmt,
        .enum_mbus_fmt  = ov5642_enum_fmt,
+       .s_crop         = ov5642_s_crop,
        .g_crop         = ov5642_g_crop,
        .cropcap        = ov5642_cropcap,
+       .g_mbus_config  = ov5642_g_mbus_config,
 };
 
 static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
+       .s_power        = ov5642_s_power,
        .g_chip_ident   = ov5642_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register     = ov5642_get_register,
@@ -877,28 +974,7 @@ static struct v4l2_subdev_ops ov5642_subdev_ops = {
        .video  = &ov5642_subdev_video_ops,
 };
 
-/*
- * We have to provide soc-camera operations, but we don't have anything to say
- * there. The MIPI CSI2 driver will provide .query_bus_param and .set_bus_param
- */
-static unsigned long soc_ov5642_query_bus_param(struct soc_camera_device *icd)
-{
-       return 0;
-}
-
-static int soc_ov5642_set_bus_param(struct soc_camera_device *icd,
-                                unsigned long flags)
-{
-       return -EINVAL;
-}
-
-static struct soc_camera_ops soc_ov5642_ops = {
-       .query_bus_param        = soc_ov5642_query_bus_param,
-       .set_bus_param          = soc_ov5642_set_bus_param,
-};
-
-static int ov5642_video_probe(struct soc_camera_device *icd,
-                             struct i2c_client *client)
+static int ov5642_video_probe(struct i2c_client *client)
 {
        int ret;
        u8 id_high, id_low;
@@ -929,16 +1005,9 @@ static int ov5642_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 {
        struct ov5642 *priv;
-       struct soc_camera_device *icd = client->dev.platform_data;
-       struct soc_camera_link *icl;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "OV5642: missing soc-camera data!\n");
-               return -EINVAL;
-       }
-
-       icl = to_soc_camera_link(icd);
        if (!icl) {
                dev_err(&client->dev, "OV5642: missing platform data!\n");
                return -EINVAL;
@@ -950,17 +1019,24 @@ static int ov5642_probe(struct i2c_client *client,
 
        v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops);
 
-       icd->ops        = &soc_ov5642_ops;
-       priv->fmt       = &ov5642_colour_fmts[0];
+       priv->fmt               = &ov5642_colour_fmts[0];
+
+       priv->crop_rect.width   = OV5642_DEFAULT_WIDTH;
+       priv->crop_rect.height  = OV5642_DEFAULT_HEIGHT;
+       priv->crop_rect.left    = (OV5642_MAX_WIDTH - OV5642_DEFAULT_WIDTH) / 2;
+       priv->crop_rect.top     = (OV5642_MAX_HEIGHT - OV5642_DEFAULT_HEIGHT) / 2;
+       priv->crop_rect.width   = OV5642_DEFAULT_WIDTH;
+       priv->crop_rect.height  = OV5642_DEFAULT_HEIGHT;
+       priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
+       priv->total_height = BLANKING_MIN_HEIGHT;
 
-       ret = ov5642_video_probe(icd, client);
+       ret = ov5642_video_probe(client);
        if (ret < 0)
                goto error;
 
        return 0;
 
 error:
-       icd->ops = NULL;
        kfree(priv);
        return ret;
 }
@@ -968,10 +1044,8 @@ error:
 static int ov5642_remove(struct i2c_client *client)
 {
        struct ov5642 *priv = to_ov5642(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
 
-       icd->ops = NULL;
        if (icl->free_bus)
                icl->free_bus(icl);
        kfree(priv);
index 456d9ad..d5b0572 100644 (file)
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
+#include <linux/v4l2-mediabus.h>
 
 #include <media/soc_camera.h>
 #include <media/v4l2-chip-ident.h>
-
+#include <media/v4l2-ctrls.h>
 
 /* Register definitions */
 #define REG_GAIN               0x00    /* range 00 - 3F */
@@ -177,20 +178,23 @@ struct ov6650_reg {
 
 struct ov6650 {
        struct v4l2_subdev      subdev;
-
-       int                     gain;
-       int                     blue;
-       int                     red;
-       int                     saturation;
-       int                     hue;
-       int                     brightness;
-       int                     exposure;
-       int                     gamma;
-       int                     aec;
-       bool                    vflip;
-       bool                    hflip;
-       bool                    awb;
-       bool                    agc;
+       struct v4l2_ctrl_handler hdl;
+       struct {
+               /* exposure/autoexposure cluster */
+               struct v4l2_ctrl *autoexposure;
+               struct v4l2_ctrl *exposure;
+       };
+       struct {
+               /* gain/autogain cluster */
+               struct v4l2_ctrl *autogain;
+               struct v4l2_ctrl *gain;
+       };
+       struct {
+               /* blue/red/autowhitebalance cluster */
+               struct v4l2_ctrl *autowb;
+               struct v4l2_ctrl *blue;
+               struct v4l2_ctrl *red;
+       };
        bool                    half_scale;     /* scale down output by 2 */
        struct v4l2_rect        rect;           /* sensor cropping window */
        unsigned long           pclk_limit;     /* from host */
@@ -210,126 +214,6 @@ static enum v4l2_mbus_pixelcode ov6650_codes[] = {
        V4L2_MBUS_FMT_Y8_1X8,
 };
 
-static const struct v4l2_queryctrl ov6650_controls[] = {
-       {
-               .id             = V4L2_CID_AUTOGAIN,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "AGC",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 1,
-       },
-       {
-               .id             = V4L2_CID_GAIN,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Gain",
-               .minimum        = 0,
-               .maximum        = 0x3f,
-               .step           = 1,
-               .default_value  = DEF_GAIN,
-       },
-       {
-               .id             = V4L2_CID_AUTO_WHITE_BALANCE,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "AWB",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 1,
-       },
-       {
-               .id             = V4L2_CID_BLUE_BALANCE,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Blue",
-               .minimum        = 0,
-               .maximum        = 0xff,
-               .step           = 1,
-               .default_value  = DEF_BLUE,
-       },
-       {
-               .id             = V4L2_CID_RED_BALANCE,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Red",
-               .minimum        = 0,
-               .maximum        = 0xff,
-               .step           = 1,
-               .default_value  = DEF_RED,
-       },
-       {
-               .id             = V4L2_CID_SATURATION,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Saturation",
-               .minimum        = 0,
-               .maximum        = 0xf,
-               .step           = 1,
-               .default_value  = 0x8,
-       },
-       {
-               .id             = V4L2_CID_HUE,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Hue",
-               .minimum        = 0,
-               .maximum        = HUE_MASK,
-               .step           = 1,
-               .default_value  = DEF_HUE,
-       },
-       {
-               .id             = V4L2_CID_BRIGHTNESS,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Brightness",
-               .minimum        = 0,
-               .maximum        = 0xff,
-               .step           = 1,
-               .default_value  = 0x80,
-       },
-       {
-               .id             = V4L2_CID_EXPOSURE_AUTO,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "AEC",
-               .minimum        = 0,
-               .maximum        = 3,
-               .step           = 1,
-               .default_value  = 0,
-       },
-       {
-               .id             = V4L2_CID_EXPOSURE,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Exposure",
-               .minimum        = 0,
-               .maximum        = 0xff,
-               .step           = 1,
-               .default_value  = DEF_AECH,
-       },
-       {
-               .id             = V4L2_CID_GAMMA,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Gamma",
-               .minimum        = 0,
-               .maximum        = 0xff,
-               .step           = 1,
-               .default_value  = 0x12,
-       },
-       {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Vertically",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-       {
-               .id             = V4L2_CID_HFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Horizontally",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-};
-
 /* read a register */
 static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val)
 {
@@ -419,213 +303,90 @@ static int ov6650_s_stream(struct v4l2_subdev *sd, int enable)
        return 0;
 }
 
-/* Alter bus settings on camera side */
-static int ov6650_set_bus_param(struct soc_camera_device *icd,
-                               unsigned long flags)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-       int ret;
-
-       flags = soc_camera_apply_sensor_flags(icl, flags);
-
-       if (flags & SOCAM_PCLK_SAMPLE_RISING)
-               ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
-       else
-               ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
-       if (ret)
-               return ret;
-
-       if (flags & SOCAM_HSYNC_ACTIVE_LOW)
-               ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
-       else
-               ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
-       if (ret)
-               return ret;
-
-       if (flags & SOCAM_VSYNC_ACTIVE_HIGH)
-               ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
-       else
-               ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
-
-       return ret;
-}
-
-/* Request bus settings on camera side */
-static unsigned long ov6650_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-
-       unsigned long flags = SOCAM_MASTER |
-               SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
-               SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
-               SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
-               SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
 /* Get status of additional camera capabilities */
-static int ov6650_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int ov6550_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 {
+       struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
+       struct v4l2_subdev *sd = &priv->subdev;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov6650 *priv = to_ov6650(client);
-       uint8_t reg;
-       int ret = 0;
+       uint8_t reg, reg2;
+       int ret;
 
        switch (ctrl->id) {
        case V4L2_CID_AUTOGAIN:
-               ctrl->value = priv->agc;
-               break;
-       case V4L2_CID_GAIN:
-               if (priv->agc) {
-                       ret = ov6650_reg_read(client, REG_GAIN, &reg);
-                       ctrl->value = reg;
-               } else {
-                       ctrl->value = priv->gain;
-               }
-               break;
+               ret = ov6650_reg_read(client, REG_GAIN, &reg);
+               if (!ret)
+                       priv->gain->val = reg;
+               return ret;
        case V4L2_CID_AUTO_WHITE_BALANCE:
-               ctrl->value = priv->awb;
-               break;
-       case V4L2_CID_BLUE_BALANCE:
-               if (priv->awb) {
-                       ret = ov6650_reg_read(client, REG_BLUE, &reg);
-                       ctrl->value = reg;
-               } else {
-                       ctrl->value = priv->blue;
-               }
-               break;
-       case V4L2_CID_RED_BALANCE:
-               if (priv->awb) {
-                       ret = ov6650_reg_read(client, REG_RED, &reg);
-                       ctrl->value = reg;
-               } else {
-                       ctrl->value = priv->red;
+               ret = ov6650_reg_read(client, REG_BLUE, &reg);
+               if (!ret)
+                       ret = ov6650_reg_read(client, REG_RED, &reg2);
+               if (!ret) {
+                       priv->blue->val = reg;
+                       priv->red->val = reg2;
                }
-               break;
-       case V4L2_CID_SATURATION:
-               ctrl->value = priv->saturation;
-               break;
-       case V4L2_CID_HUE:
-               ctrl->value = priv->hue;
-               break;
-       case V4L2_CID_BRIGHTNESS:
-               ctrl->value = priv->brightness;
-               break;
+               return ret;
        case V4L2_CID_EXPOSURE_AUTO:
-               ctrl->value = priv->aec;
-               break;
-       case V4L2_CID_EXPOSURE:
-               if (priv->aec) {
-                       ret = ov6650_reg_read(client, REG_AECH, &reg);
-                       ctrl->value = reg;
-               } else {
-                       ctrl->value = priv->exposure;
-               }
-               break;
-       case V4L2_CID_GAMMA:
-               ctrl->value = priv->gamma;
-               break;
-       case V4L2_CID_VFLIP:
-               ctrl->value = priv->vflip;
-               break;
-       case V4L2_CID_HFLIP:
-               ctrl->value = priv->hflip;
-               break;
+               ret = ov6650_reg_read(client, REG_AECH, &reg);
+               if (!ret)
+                       priv->exposure->val = reg;
+               return ret;
        }
-       return ret;
+       return -EINVAL;
 }
 
 /* Set status of additional camera capabilities */
-static int ov6650_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int ov6550_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+       struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
+       struct v4l2_subdev *sd = &priv->subdev;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov6650 *priv = to_ov6650(client);
-       int ret = 0;
+       int ret;
 
        switch (ctrl->id) {
        case V4L2_CID_AUTOGAIN:
                ret = ov6650_reg_rmw(client, REG_COMB,
-                               ctrl->value ? COMB_AGC : 0, COMB_AGC);
-               if (!ret)
-                       priv->agc = ctrl->value;
-               break;
-       case V4L2_CID_GAIN:
-               ret = ov6650_reg_write(client, REG_GAIN, ctrl->value);
-               if (!ret)
-                       priv->gain = ctrl->value;
-               break;
+                               ctrl->val ? COMB_AGC : 0, COMB_AGC);
+               if (!ret && !ctrl->val)
+                       ret = ov6650_reg_write(client, REG_GAIN, priv->gain->val);
+               return ret;
        case V4L2_CID_AUTO_WHITE_BALANCE:
                ret = ov6650_reg_rmw(client, REG_COMB,
-                               ctrl->value ? COMB_AWB : 0, COMB_AWB);
-               if (!ret)
-                       priv->awb = ctrl->value;
-               break;
-       case V4L2_CID_BLUE_BALANCE:
-               ret = ov6650_reg_write(client, REG_BLUE, ctrl->value);
-               if (!ret)
-                       priv->blue = ctrl->value;
-               break;
-       case V4L2_CID_RED_BALANCE:
-               ret = ov6650_reg_write(client, REG_RED, ctrl->value);
-               if (!ret)
-                       priv->red = ctrl->value;
-               break;
+                               ctrl->val ? COMB_AWB : 0, COMB_AWB);
+               if (!ret && !ctrl->val) {
+                       ret = ov6650_reg_write(client, REG_BLUE, priv->blue->val);
+                       if (!ret)
+                               ret = ov6650_reg_write(client, REG_RED,
+                                                       priv->red->val);
+               }
+               return ret;
        case V4L2_CID_SATURATION:
-               ret = ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->value),
+               return ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->val),
                                SAT_MASK);
-               if (!ret)
-                       priv->saturation = ctrl->value;
-               break;
        case V4L2_CID_HUE:
-               ret = ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->value),
+               return ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->val),
                                HUE_MASK);
-               if (!ret)
-                       priv->hue = ctrl->value;
-               break;
        case V4L2_CID_BRIGHTNESS:
-               ret = ov6650_reg_write(client, REG_BRT, ctrl->value);
-               if (!ret)
-                       priv->brightness = ctrl->value;
-               break;
+               return ov6650_reg_write(client, REG_BRT, ctrl->val);
        case V4L2_CID_EXPOSURE_AUTO:
-               switch (ctrl->value) {
-               case V4L2_EXPOSURE_AUTO:
-                       ret = ov6650_reg_rmw(client, REG_COMB, COMB_AEC, 0);
-                       break;
-               default:
-                       ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_AEC);
-                       break;
-               }
-               if (!ret)
-                       priv->aec = ctrl->value;
-               break;
-       case V4L2_CID_EXPOSURE:
-               ret = ov6650_reg_write(client, REG_AECH, ctrl->value);
-               if (!ret)
-                       priv->exposure = ctrl->value;
-               break;
+               ret = ov6650_reg_rmw(client, REG_COMB, ctrl->val ==
+                               V4L2_EXPOSURE_AUTO ? COMB_AEC : 0, COMB_AEC);
+               if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL)
+                       ret = ov6650_reg_write(client, REG_AECH,
+                                               priv->exposure->val);
+               return ret;
        case V4L2_CID_GAMMA:
-               ret = ov6650_reg_write(client, REG_GAM1, ctrl->value);
-               if (!ret)
-                       priv->gamma = ctrl->value;
-               break;
+               return ov6650_reg_write(client, REG_GAM1, ctrl->val);
        case V4L2_CID_VFLIP:
-               ret = ov6650_reg_rmw(client, REG_COMB,
-                               ctrl->value ? COMB_FLIP_V : 0, COMB_FLIP_V);
-               if (!ret)
-                       priv->vflip = ctrl->value;
-               break;
+               return ov6650_reg_rmw(client, REG_COMB,
+                               ctrl->val ? COMB_FLIP_V : 0, COMB_FLIP_V);
        case V4L2_CID_HFLIP:
-               ret = ov6650_reg_rmw(client, REG_COMB,
-                               ctrl->value ? COMB_FLIP_H : 0, COMB_FLIP_H);
-               if (!ret)
-                       priv->hflip = ctrl->value;
-               break;
+               return ov6650_reg_rmw(client, REG_COMB,
+                               ctrl->val ? COMB_FLIP_H : 0, COMB_FLIP_H);
        }
 
-       return ret;
+       return -EINVAL;
 }
 
 /* Get chip identification */
@@ -778,7 +539,7 @@ static u8 to_clkrc(struct v4l2_fract *timeperframe,
 static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_device *icd = client->dev.platform_data;
+       struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id;
        struct soc_camera_sense *sense = icd->sense;
        struct ov6650 *priv = to_ov6650(client);
        bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect);
@@ -1057,8 +818,7 @@ static int ov6650_prog_dflt(struct i2c_client *client)
        return ret;
 }
 
-static int ov6650_video_probe(struct soc_camera_device *icd,
-                               struct i2c_client *client)
+static int ov6650_video_probe(struct i2c_client *client)
 {
        u8              pidh, pidl, midh, midl;
        int             ret = 0;
@@ -1094,16 +854,12 @@ static int ov6650_video_probe(struct soc_camera_device *icd,
        return ret;
 }
 
-static struct soc_camera_ops ov6650_ops = {
-       .set_bus_param          = ov6650_set_bus_param,
-       .query_bus_param        = ov6650_query_bus_param,
-       .controls               = ov6650_controls,
-       .num_controls           = ARRAY_SIZE(ov6650_controls),
+static const struct v4l2_ctrl_ops ov6550_ctrl_ops = {
+       .g_volatile_ctrl = ov6550_g_volatile_ctrl,
+       .s_ctrl = ov6550_s_ctrl,
 };
 
 static struct v4l2_subdev_core_ops ov6650_core_ops = {
-       .g_ctrl                 = ov6650_g_ctrl,
-       .s_ctrl                 = ov6650_s_ctrl,
        .g_chip_ident           = ov6650_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register             = ov6650_get_register,
@@ -1111,6 +867,55 @@ static struct v4l2_subdev_core_ops ov6650_core_ops = {
 #endif
 };
 
+/* Request bus settings on camera side */
+static int ov6650_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_MASTER |
+               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
+/* Alter bus settings on camera side */
+static int ov6650_s_mbus_config(struct v4l2_subdev *sd,
+                               const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+       unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
+       int ret;
+
+       if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+               ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
+       else
+               ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
+       if (ret)
+               return ret;
+
+       if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+               ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
+       else
+               ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
+       if (ret)
+               return ret;
+
+       if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+               ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
+       else
+               ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
+
+       return ret;
+}
+
 static struct v4l2_subdev_video_ops ov6650_video_ops = {
        .s_stream       = ov6650_s_stream,
        .g_mbus_fmt     = ov6650_g_fmt,
@@ -1122,6 +927,8 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = {
        .s_crop         = ov6650_s_crop,
        .g_parm         = ov6650_g_parm,
        .s_parm         = ov6650_s_parm,
+       .g_mbus_config  = ov6650_g_mbus_config,
+       .s_mbus_config  = ov6650_s_mbus_config,
 };
 
 static struct v4l2_subdev_ops ov6650_subdev_ops = {
@@ -1136,16 +943,9 @@ static int ov6650_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 {
        struct ov6650 *priv;
-       struct soc_camera_device *icd = client->dev.platform_data;
-       struct soc_camera_link *icl;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "Missing soc-camera data!\n");
-               return -EINVAL;
-       }
-
-       icl = to_soc_camera_link(icd);
        if (!icl) {
                dev_err(&client->dev, "Missing platform_data for driver\n");
                return -EINVAL;
@@ -1159,8 +959,46 @@ static int ov6650_probe(struct i2c_client *client,
        }
 
        v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops);
+       v4l2_ctrl_handler_init(&priv->hdl, 13);
+       v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       priv->autogain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
+       priv->gain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_GAIN, 0, 0x3f, 1, DEF_GAIN);
+       priv->autowb = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
+       priv->blue = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_BLUE_BALANCE, 0, 0xff, 1, DEF_BLUE);
+       priv->red = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_RED_BALANCE, 0, 0xff, 1, DEF_RED);
+       v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_SATURATION, 0, 0xf, 1, 0x8);
+       v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_HUE, 0, HUE_MASK, 1, DEF_HUE);
+       v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x80);
+       priv->autoexposure = v4l2_ctrl_new_std_menu(&priv->hdl,
+                       &ov6550_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
+                       V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
+       priv->exposure = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_EXPOSURE, 0, 0xff, 1, DEF_AECH);
+       v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
+                       V4L2_CID_GAMMA, 0, 0xff, 1, 0x12);
+
+       priv->subdev.ctrl_handler = &priv->hdl;
+       if (priv->hdl.error) {
+               int err = priv->hdl.error;
 
-       icd->ops = &ov6650_ops;
+               kfree(priv);
+               return err;
+       }
+       v4l2_ctrl_auto_cluster(2, &priv->autogain, 0, true);
+       v4l2_ctrl_auto_cluster(3, &priv->autowb, 0, true);
+       v4l2_ctrl_auto_cluster(2, &priv->autoexposure,
+                               V4L2_EXPOSURE_MANUAL, true);
 
        priv->rect.left   = DEF_HSTRT << 1;
        priv->rect.top    = DEF_VSTRT << 1;
@@ -1170,10 +1008,12 @@ static int ov6650_probe(struct i2c_client *client,
        priv->code        = V4L2_MBUS_FMT_YUYV8_2X8;
        priv->colorspace  = V4L2_COLORSPACE_JPEG;
 
-       ret = ov6650_video_probe(icd, client);
+       ret = ov6650_video_probe(client);
+       if (!ret)
+               ret = v4l2_ctrl_handler_setup(&priv->hdl);
 
        if (ret) {
-               icd->ops = NULL;
+               v4l2_ctrl_handler_free(&priv->hdl);
                kfree(priv);
        }
 
@@ -1184,6 +1024,8 @@ static int ov6650_remove(struct i2c_client *client)
 {
        struct ov6650 *priv = to_ov6650(client);
 
+       v4l2_device_unregister_subdev(&priv->subdev);
+       v4l2_ctrl_handler_free(&priv->hdl);
        kfree(priv);
        return 0;
 }
index 397870f..9f6ce3d 100644 (file)
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
+
+#include <media/ov772x.h>
+#include <media/soc_camera.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-subdev.h>
-#include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
-#include <media/ov772x.h>
 
 /*
  * register offset
@@ -400,6 +402,7 @@ struct ov772x_win_size {
 
 struct ov772x_priv {
        struct v4l2_subdev                subdev;
+       struct v4l2_ctrl_handler          hdl;
        struct ov772x_camera_info        *info;
        const struct ov772x_color_format *cfmt;
        const struct ov772x_win_size     *win;
@@ -517,36 +520,6 @@ static const struct ov772x_win_size ov772x_win_qvga = {
        .regs     = ov772x_qvga_regs,
 };
 
-static const struct v4l2_queryctrl ov772x_controls[] = {
-       {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Vertically",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-       {
-               .id             = V4L2_CID_HFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Horizontally",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-       {
-               .id             = V4L2_CID_BAND_STOP_FILTER,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Band-stop filter",
-               .minimum        = 0,
-               .maximum        = 256,
-               .step           = 1,
-               .default_value  = 0,
-       },
-};
-
 /*
  * general function
  */
@@ -620,75 +593,30 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
        return 0;
 }
 
-static int ov772x_set_bus_param(struct soc_camera_device *icd,
-                               unsigned long             flags)
-{
-       return 0;
-}
-
-static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
-{
-       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-       struct ov772x_priv *priv = i2c_get_clientdata(client);
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
-               SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
-               SOCAM_DATA_ACTIVE_HIGH;
-
-       if (priv->info->flags & OV772X_FLAG_8BIT)
-               flags |= SOCAM_DATAWIDTH_8;
-       else
-               flags |= SOCAM_DATAWIDTH_10;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
-static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-       struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               ctrl->value = priv->flag_vflip;
-               break;
-       case V4L2_CID_HFLIP:
-               ctrl->value = priv->flag_hflip;
-               break;
-       case V4L2_CID_BAND_STOP_FILTER:
-               ctrl->value = priv->band_filter;
-               break;
-       }
-       return 0;
-}
-
-static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+       struct ov772x_priv *priv = container_of(ctrl->handler,
+                                               struct ov772x_priv, hdl);
+       struct v4l2_subdev *sd = &priv->subdev;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
        int ret = 0;
        u8 val;
 
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               val = ctrl->value ? VFLIP_IMG : 0x00;
-               priv->flag_vflip = ctrl->value;
+               val = ctrl->val ? VFLIP_IMG : 0x00;
+               priv->flag_vflip = ctrl->val;
                if (priv->info->flags & OV772X_FLAG_VFLIP)
                        val ^= VFLIP_IMG;
-               ret = ov772x_mask_set(client, COM3, VFLIP_IMG, val);
-               break;
+               return ov772x_mask_set(client, COM3, VFLIP_IMG, val);
        case V4L2_CID_HFLIP:
-               val = ctrl->value ? HFLIP_IMG : 0x00;
-               priv->flag_hflip = ctrl->value;
+               val = ctrl->val ? HFLIP_IMG : 0x00;
+               priv->flag_hflip = ctrl->val;
                if (priv->info->flags & OV772X_FLAG_HFLIP)
                        val ^= HFLIP_IMG;
-               ret = ov772x_mask_set(client, COM3, HFLIP_IMG, val);
-               break;
+               return ov772x_mask_set(client, COM3, HFLIP_IMG, val);
        case V4L2_CID_BAND_STOP_FILTER:
-               if ((unsigned)ctrl->value > 256)
-                       ctrl->value = 256;
-               if (ctrl->value == priv->band_filter)
-                       break;
-               if (!ctrl->value) {
+               if (!ctrl->val) {
                        /* Switch the filter off, it is on now */
                        ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
                        if (!ret)
@@ -696,7 +624,7 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
                                                      BNDF_ON_OFF, 0);
                } else {
                        /* Switch the filter on, set AEC low limit */
-                       val = 256 - ctrl->value;
+                       val = 256 - ctrl->val;
                        ret = ov772x_mask_set(client, COM8,
                                              BNDF_ON_OFF, BNDF_ON_OFF);
                        if (!ret)
@@ -704,11 +632,11 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
                                                      0xff, val);
                }
                if (!ret)
-                       priv->band_filter = ctrl->value;
-               break;
+                       priv->band_filter = ctrl->val;
+               return ret;
        }
 
-       return ret;
+       return -EINVAL;
 }
 
 static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
@@ -822,13 +750,13 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
                        goto ov772x_set_fmt_error;
 
                ret = ov772x_mask_set(client,
-                                     EDGE_TRSHLD, EDGE_THRESHOLD_MASK,
+                                     EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK,
                                      priv->info->edgectrl.threshold);
                if (ret < 0)
                        goto ov772x_set_fmt_error;
 
                ret = ov772x_mask_set(client,
-                                     EDGE_STRNGT, EDGE_STRENGTH_MASK,
+                                     EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK,
                                      priv->info->edgectrl.strength);
                if (ret < 0)
                        goto ov772x_set_fmt_error;
@@ -840,13 +768,13 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
                 * set upper and lower limit
                 */
                ret = ov772x_mask_set(client,
-                                     EDGE_UPPER, EDGE_UPPER_MASK,
+                                     EDGE_UPPER, OV772X_EDGE_UPPER_MASK,
                                      priv->info->edgectrl.upper);
                if (ret < 0)
                        goto ov772x_set_fmt_error;
 
                ret = ov772x_mask_set(client,
-                                     EDGE_LOWER, EDGE_LOWER_MASK,
+                                     EDGE_LOWER, OV772X_EDGE_LOWER_MASK,
                                      priv->info->edgectrl.lower);
                if (ret < 0)
                        goto ov772x_set_fmt_error;
@@ -1025,17 +953,12 @@ static int ov772x_try_fmt(struct v4l2_subdev *sd,
        return 0;
 }
 
-static int ov772x_video_probe(struct soc_camera_device *icd,
-                             struct i2c_client *client)
+static int ov772x_video_probe(struct i2c_client *client)
 {
        struct ov772x_priv *priv = to_ov772x(client);
        u8                  pid, ver;
        const char         *devname;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
        /*
         * check and show product ID and manufacturer ID
         */
@@ -1064,20 +987,14 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
                 ver,
                 i2c_smbus_read_byte_data(client, MIDH),
                 i2c_smbus_read_byte_data(client, MIDL));
-
-       return 0;
+       return v4l2_ctrl_handler_setup(&priv->hdl);
 }
 
-static struct soc_camera_ops ov772x_ops = {
-       .set_bus_param          = ov772x_set_bus_param,
-       .query_bus_param        = ov772x_query_bus_param,
-       .controls               = ov772x_controls,
-       .num_controls           = ARRAY_SIZE(ov772x_controls),
+static const struct v4l2_ctrl_ops ov772x_ctrl_ops = {
+       .s_ctrl = ov772x_s_ctrl,
 };
 
 static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
-       .g_ctrl         = ov772x_g_ctrl,
-       .s_ctrl         = ov772x_s_ctrl,
        .g_chip_ident   = ov772x_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register     = ov772x_g_register,
@@ -1095,6 +1012,21 @@ static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
        return 0;
 }
 
+static int ov772x_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
 static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
        .s_stream       = ov772x_s_stream,
        .g_mbus_fmt     = ov772x_g_fmt,
@@ -1103,6 +1035,7 @@ static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
        .cropcap        = ov772x_cropcap,
        .g_crop         = ov772x_g_crop,
        .enum_mbus_fmt  = ov772x_enum_fmt,
+       .g_mbus_config  = ov772x_g_mbus_config,
 };
 
 static struct v4l2_subdev_ops ov772x_subdev_ops = {
@@ -1117,20 +1050,15 @@ static struct v4l2_subdev_ops ov772x_subdev_ops = {
 static int ov772x_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 {
-       struct ov772x_priv        *priv;
-       struct soc_camera_device  *icd = client->dev.platform_data;
-       struct i2c_adapter        *adapter = to_i2c_adapter(client->dev.parent);
-       struct soc_camera_link    *icl;
-       int                        ret;
-
-       if (!icd) {
-               dev_err(&client->dev, "OV772X: missing soc-camera data!\n");
-               return -EINVAL;
-       }
+       struct ov772x_priv      *priv;
+       struct soc_camera_link  *icl = soc_camera_i2c_to_link(client);
+       struct i2c_adapter      *adapter = to_i2c_adapter(client->dev.parent);
+       int                     ret;
 
-       icl = to_soc_camera_link(icd);
-       if (!icl || !icl->priv)
+       if (!icl || !icl->priv) {
+               dev_err(&client->dev, "OV772X: missing platform data!\n");
                return -EINVAL;
+       }
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
                dev_err(&adapter->dev,
@@ -1146,12 +1074,24 @@ static int ov772x_probe(struct i2c_client *client,
        priv->info = icl->priv;
 
        v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
+       v4l2_ctrl_handler_init(&priv->hdl, 3);
+       v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
+                       V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0);
+       priv->subdev.ctrl_handler = &priv->hdl;
+       if (priv->hdl.error) {
+               int err = priv->hdl.error;
 
-       icd->ops                = &ov772x_ops;
+               kfree(priv);
+               return err;
+       }
 
-       ret = ov772x_video_probe(icd, client);
+       ret = ov772x_video_probe(client);
        if (ret) {
-               icd->ops = NULL;
+               v4l2_ctrl_handler_free(&priv->hdl);
                kfree(priv);
        }
 
@@ -1161,9 +1101,9 @@ static int ov772x_probe(struct i2c_client *client,
 static int ov772x_remove(struct i2c_client *client)
 {
        struct ov772x_priv *priv = to_ov772x(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
 
-       icd->ops = NULL;
+       v4l2_device_unregister_subdev(&priv->subdev);
+       v4l2_ctrl_handler_free(&priv->hdl);
        kfree(priv);
        return 0;
 }
index 3681a6f..a4f9979 100644 (file)
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
+
+#include <media/soc_camera.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
-#include <media/soc_camera.h>
+#include <media/v4l2-ctrls.h>
 
 #include "ov9640.h"
 
@@ -162,27 +165,6 @@ static enum v4l2_mbus_pixelcode ov9640_codes[] = {
        V4L2_MBUS_FMT_RGB565_2X8_LE,
 };
 
-static const struct v4l2_queryctrl ov9640_controls[] = {
-       {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Vertically",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-       {
-               .id             = V4L2_CID_HFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Horizontally",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-};
-
 /* read a register */
 static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
 {
@@ -284,75 +266,25 @@ static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
        return 0;
 }
 
-/* Alter bus settings on camera side */
-static int ov9640_set_bus_param(struct soc_camera_device *icd,
-                               unsigned long flags)
-{
-       return 0;
-}
-
-/* Request bus settings on camera side */
-static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-
-       /*
-        * REVISIT: the camera probably can do 10 bit transfers, but I don't
-        *          have those pins connected on my hardware.
-        */
-       unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
-               SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
-               SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
-/* Get status of additional camera capabilities */
-static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-       struct ov9640_priv *priv = to_ov9640_sensor(sd);
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               ctrl->value = priv->flag_vflip;
-               break;
-       case V4L2_CID_HFLIP:
-               ctrl->value = priv->flag_hflip;
-               break;
-       }
-       return 0;
-}
-
 /* Set status of additional camera capabilities */
-static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int ov9640_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct ov9640_priv *priv = to_ov9640_sensor(sd);
-
-       int ret = 0;
+       struct ov9640_priv *priv = container_of(ctrl->handler, struct ov9640_priv, hdl);
+       struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
 
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               priv->flag_vflip = ctrl->value;
-               if (ctrl->value)
-                       ret = ov9640_reg_rmw(client, OV9640_MVFP,
+               if (ctrl->val)
+                       return ov9640_reg_rmw(client, OV9640_MVFP,
                                                        OV9640_MVFP_V, 0);
-               else
-                       ret = ov9640_reg_rmw(client, OV9640_MVFP,
-                                                       0, OV9640_MVFP_V);
-               break;
+               return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_V);
        case V4L2_CID_HFLIP:
-               priv->flag_hflip = ctrl->value;
-               if (ctrl->value)
-                       ret = ov9640_reg_rmw(client, OV9640_MVFP,
+               if (ctrl->val)
+                       return ov9640_reg_rmw(client, OV9640_MVFP,
                                                        OV9640_MVFP_H, 0);
-               else
-                       ret = ov9640_reg_rmw(client, OV9640_MVFP,
-                                                       0, OV9640_MVFP_H);
-               break;
+               return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_H);
        }
-
-       return ret;
+       return -EINVAL;
 }
 
 /* Get chip identification */
@@ -646,10 +578,7 @@ static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
        return 0;
 }
 
-
-
-static int ov9640_video_probe(struct soc_camera_device *icd,
-                               struct i2c_client *client)
+static int ov9640_video_probe(struct i2c_client *client)
 {
        struct v4l2_subdev *sd = i2c_get_clientdata(client);
        struct ov9640_priv *priv = to_ov9640_sensor(sd);
@@ -657,29 +586,19 @@ static int ov9640_video_probe(struct soc_camera_device *icd,
        const char      *devname;
        int             ret = 0;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
        /*
         * check and show product ID and manufacturer ID
         */
 
        ret = ov9640_reg_read(client, OV9640_PID, &pid);
+       if (!ret)
+               ret = ov9640_reg_read(client, OV9640_VER, &ver);
+       if (!ret)
+               ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
+       if (!ret)
+               ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
        if (ret)
-               goto err;
-
-       ret = ov9640_reg_read(client, OV9640_VER, &ver);
-       if (ret)
-               goto err;
-
-       ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
-       if (ret)
-               goto err;
-
-       ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
-       if (ret)
-               goto err;
+               return ret;
 
        switch (VERSION(pid, ver)) {
        case OV9640_V2:
@@ -693,27 +612,20 @@ static int ov9640_video_probe(struct soc_camera_device *icd,
                break;
        default:
                dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
-               ret = -ENODEV;
-               goto err;
+               return -ENODEV;
        }
 
        dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
                 devname, pid, ver, midh, midl);
 
-err:
-       return ret;
+       return v4l2_ctrl_handler_setup(&priv->hdl);
 }
 
-static struct soc_camera_ops ov9640_ops = {
-       .set_bus_param          = ov9640_set_bus_param,
-       .query_bus_param        = ov9640_query_bus_param,
-       .controls               = ov9640_controls,
-       .num_controls           = ARRAY_SIZE(ov9640_controls),
+static const struct v4l2_ctrl_ops ov9640_ctrl_ops = {
+       .s_ctrl = ov9640_s_ctrl,
 };
 
 static struct v4l2_subdev_core_ops ov9640_core_ops = {
-       .g_ctrl                 = ov9640_g_ctrl,
-       .s_ctrl                 = ov9640_s_ctrl,
        .g_chip_ident           = ov9640_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register             = ov9640_get_register,
@@ -722,6 +634,22 @@ static struct v4l2_subdev_core_ops ov9640_core_ops = {
 
 };
 
+/* Request bus settings on camera side */
+static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
 static struct v4l2_subdev_video_ops ov9640_video_ops = {
        .s_stream       = ov9640_s_stream,
        .s_mbus_fmt     = ov9640_s_fmt,
@@ -729,7 +657,7 @@ static struct v4l2_subdev_video_ops ov9640_video_ops = {
        .enum_mbus_fmt  = ov9640_enum_fmt,
        .cropcap        = ov9640_cropcap,
        .g_crop         = ov9640_g_crop,
-
+       .g_mbus_config  = ov9640_g_mbus_config,
 };
 
 static struct v4l2_subdev_ops ov9640_subdev_ops = {
@@ -744,16 +672,9 @@ static int ov9640_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 {
        struct ov9640_priv *priv;
-       struct soc_camera_device *icd   = client->dev.platform_data;
-       struct soc_camera_link *icl;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "Missing soc-camera data!\n");
-               return -EINVAL;
-       }
-
-       icl = to_soc_camera_link(icd);
        if (!icl) {
                dev_err(&client->dev, "Missing platform_data for driver\n");
                return -EINVAL;
@@ -768,12 +689,23 @@ static int ov9640_probe(struct i2c_client *client,
 
        v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
 
-       icd->ops        = &ov9640_ops;
+       v4l2_ctrl_handler_init(&priv->hdl, 2);
+       v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       priv->subdev.ctrl_handler = &priv->hdl;
+       if (priv->hdl.error) {
+               int err = priv->hdl.error;
+
+               kfree(priv);
+               return err;
+       }
 
-       ret = ov9640_video_probe(icd, client);
+       ret = ov9640_video_probe(client);
 
        if (ret) {
-               icd->ops = NULL;
+               v4l2_ctrl_handler_free(&priv->hdl);
                kfree(priv);
        }
 
@@ -785,6 +717,8 @@ static int ov9640_remove(struct i2c_client *client)
        struct v4l2_subdev *sd = i2c_get_clientdata(client);
        struct ov9640_priv *priv = to_ov9640_sensor(sd);
 
+       v4l2_device_unregister_subdev(&priv->subdev);
+       v4l2_ctrl_handler_free(&priv->hdl);
        kfree(priv);
        return 0;
 }
index f8a51b7..6b33a97 100644 (file)
@@ -198,12 +198,10 @@ struct ov9640_reg {
 
 struct ov9640_priv {
        struct v4l2_subdev              subdev;
+       struct v4l2_ctrl_handler        hdl;
 
        int                             model;
        int                             revision;
-
-       bool                            flag_vflip;
-       bool                            flag_hflip;
 };
 
 #endif /* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */
index edd1ffc..d9a9f71 100644 (file)
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
-#include <media/v4l2-chip-ident.h>
+#include <linux/v4l2-mediabus.h>
+
 #include <media/soc_camera.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ctrls.h>
 
 #define to_ov9740(sd)          container_of(sd, struct ov9740_priv, subdev)
 
@@ -192,6 +195,7 @@ struct ov9740_reg {
 
 struct ov9740_priv {
        struct v4l2_subdev              subdev;
+       struct v4l2_ctrl_handler        hdl;
 
        int                             ident;
        u16                             model;
@@ -392,27 +396,6 @@ static enum v4l2_mbus_pixelcode ov9740_codes[] = {
        V4L2_MBUS_FMT_YUYV8_2X8,
 };
 
-static const struct v4l2_queryctrl ov9740_controls[] = {
-       {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Vertically",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-       {
-               .id             = V4L2_CID_HFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Horizontally",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-};
-
 /* read a register */
 static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val)
 {
@@ -560,25 +543,6 @@ static int ov9740_s_stream(struct v4l2_subdev *sd, int enable)
        return ret;
 }
 
-/* Alter bus settings on camera side */
-static int ov9740_set_bus_param(struct soc_camera_device *icd,
-                               unsigned long flags)
-{
-       return 0;
-}
-
-/* Request bus settings on camera side */
-static unsigned long ov9740_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-
-       unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
-               SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
-               SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
 /* select nearest higher resolution for capture */
 static void ov9740_res_roundup(u32 *width, u32 *height)
 {
@@ -788,36 +752,18 @@ static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
        return 0;
 }
 
-/* Get status of additional camera capabilities */
-static int ov9740_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-       struct ov9740_priv *priv = to_ov9740(sd);
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               ctrl->value = priv->flag_vflip;
-               break;
-       case V4L2_CID_HFLIP:
-               ctrl->value = priv->flag_hflip;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
 /* Set status of additional camera capabilities */
-static int ov9740_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int ov9740_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-       struct ov9740_priv *priv = to_ov9740(sd);
+       struct ov9740_priv *priv =
+               container_of(ctrl->handler, struct ov9740_priv, hdl);
 
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               priv->flag_vflip = ctrl->value;
+               priv->flag_vflip = ctrl->val;
                break;
        case V4L2_CID_HFLIP:
-               priv->flag_hflip = ctrl->value;
+               priv->flag_hflip = ctrl->val;
                break;
        default:
                return -EINVAL;
@@ -890,18 +836,13 @@ static int ov9740_set_register(struct v4l2_subdev *sd,
 }
 #endif
 
-static int ov9740_video_probe(struct soc_camera_device *icd,
-                             struct i2c_client *client)
+static int ov9740_video_probe(struct i2c_client *client)
 {
        struct v4l2_subdev *sd = i2c_get_clientdata(client);
        struct ov9740_priv *priv = to_ov9740(sd);
        u8 modelhi, modello;
        int ret;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
        /*
         * check and show product ID and manufacturer ID
         */
@@ -942,25 +883,33 @@ err:
        return ret;
 }
 
-static struct soc_camera_ops ov9740_ops = {
-       .set_bus_param          = ov9740_set_bus_param,
-       .query_bus_param        = ov9740_query_bus_param,
-       .controls               = ov9740_controls,
-       .num_controls           = ARRAY_SIZE(ov9740_controls),
-};
+/* Request bus settings on camera side */
+static int ov9740_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
 
 static struct v4l2_subdev_video_ops ov9740_video_ops = {
-       .s_stream               = ov9740_s_stream,
-       .s_mbus_fmt             = ov9740_s_fmt,
-       .try_mbus_fmt           = ov9740_try_fmt,
-       .enum_mbus_fmt          = ov9740_enum_fmt,
-       .cropcap                = ov9740_cropcap,
-       .g_crop                 = ov9740_g_crop,
+       .s_stream       = ov9740_s_stream,
+       .s_mbus_fmt     = ov9740_s_fmt,
+       .try_mbus_fmt   = ov9740_try_fmt,
+       .enum_mbus_fmt  = ov9740_enum_fmt,
+       .cropcap        = ov9740_cropcap,
+       .g_crop         = ov9740_g_crop,
+       .g_mbus_config  = ov9740_g_mbus_config,
 };
 
 static struct v4l2_subdev_core_ops ov9740_core_ops = {
-       .g_ctrl                 = ov9740_g_ctrl,
-       .s_ctrl                 = ov9740_s_ctrl,
        .g_chip_ident           = ov9740_g_chip_ident,
        .s_power                = ov9740_s_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -974,6 +923,10 @@ static struct v4l2_subdev_ops ov9740_subdev_ops = {
        .video                  = &ov9740_video_ops,
 };
 
+static const struct v4l2_ctrl_ops ov9740_ctrl_ops = {
+       .s_ctrl = ov9740_s_ctrl,
+};
+
 /*
  * i2c_driver function
  */
@@ -981,16 +934,9 @@ static int ov9740_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 {
        struct ov9740_priv *priv;
-       struct soc_camera_device *icd   = client->dev.platform_data;
-       struct soc_camera_link *icl;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "Missing soc-camera data!\n");
-               return -EINVAL;
-       }
-
-       icl = to_soc_camera_link(icd);
        if (!icl) {
                dev_err(&client->dev, "Missing platform_data for driver\n");
                return -EINVAL;
@@ -1003,12 +949,24 @@ static int ov9740_probe(struct i2c_client *client,
        }
 
        v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
+       v4l2_ctrl_handler_init(&priv->hdl, 13);
+       v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       priv->subdev.ctrl_handler = &priv->hdl;
+       if (priv->hdl.error) {
+               int err = priv->hdl.error;
 
-       icd->ops = &ov9740_ops;
+               kfree(priv);
+               return err;
+       }
 
-       ret = ov9740_video_probe(icd, client);
+       ret = ov9740_video_probe(client);
+       if (!ret)
+               ret = v4l2_ctrl_handler_setup(&priv->hdl);
        if (ret < 0) {
-               icd->ops = NULL;
+               v4l2_ctrl_handler_free(&priv->hdl);
                kfree(priv);
        }
 
@@ -1019,8 +977,9 @@ static int ov9740_remove(struct i2c_client *client)
 {
        struct ov9740_priv *priv = i2c_get_clientdata(client);
 
+       v4l2_device_unregister_subdev(&priv->subdev);
+       v4l2_ctrl_handler_free(&priv->hdl);
        kfree(priv);
-
        return 0;
 }
 
index 360be22..01ff643 100644 (file)
@@ -744,9 +744,9 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
 /***************************************************************************/
 /* Videobuf2 operations */
 
-static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-                               unsigned int *nplanes, unsigned int sizes[],
-                               void *alloc_ctxs[])
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+                               unsigned int *nbuffers, unsigned int *nplanes,
+                               unsigned int sizes[], void *alloc_ctxs[])
 {
        struct pwc_device *pdev = vb2_get_drv_priv(vq);
 
index d07df22..79fb22c 100644 (file)
@@ -214,6 +214,7 @@ struct pxa_camera_dev {
        unsigned long           ciclk;
        unsigned long           mclk;
        u32                     mclk_divisor;
+       u16                     width_flags;    /* max 10 bits */
 
        struct list_head        capture;
 
@@ -1020,37 +1021,20 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
         * quick capture interface supports both.
         */
        *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
-                 SOCAM_MASTER : SOCAM_SLAVE) |
-               SOCAM_HSYNC_ACTIVE_HIGH |
-               SOCAM_HSYNC_ACTIVE_LOW |
-               SOCAM_VSYNC_ACTIVE_HIGH |
-               SOCAM_VSYNC_ACTIVE_LOW |
-               SOCAM_DATA_ACTIVE_HIGH |
-               SOCAM_PCLK_SAMPLE_RISING |
-               SOCAM_PCLK_SAMPLE_FALLING;
+                 V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_HSYNC_ACTIVE_LOW |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_VSYNC_ACTIVE_LOW |
+               V4L2_MBUS_DATA_ACTIVE_HIGH |
+               V4L2_MBUS_PCLK_SAMPLE_RISING |
+               V4L2_MBUS_PCLK_SAMPLE_FALLING;
 
        /* If requested data width is supported by the platform, use it */
-       switch (buswidth) {
-       case 10:
-               if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10))
-                       return -EINVAL;
-               *flags |= SOCAM_DATAWIDTH_10;
-               break;
-       case 9:
-               if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9))
-                       return -EINVAL;
-               *flags |= SOCAM_DATAWIDTH_9;
-               break;
-       case 8:
-               if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8))
-                       return -EINVAL;
-               *flags |= SOCAM_DATAWIDTH_8;
-               break;
-       default:
-               return -EINVAL;
-       }
+       if ((1 << (buswidth - 1)) & pcdev->width_flags)
+               return 0;
 
-       return 0;
+       return -EINVAL;
 }
 
 static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
@@ -1070,12 +1054,12 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
         * Datawidth is now guaranteed to be equal to one of the three values.
         * We fix bit-per-pixel equal to data-width...
         */
-       switch (flags & SOCAM_DATAWIDTH_MASK) {
-       case SOCAM_DATAWIDTH_10:
+       switch (icd->current_fmt->host_fmt->bits_per_sample) {
+       case 10:
                dw = 4;
                bpp = 0x40;
                break;
-       case SOCAM_DATAWIDTH_9:
+       case 9:
                dw = 3;
                bpp = 0x20;
                break;
@@ -1084,7 +1068,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
                 * Actually it can only be 8 now,
                 * default is just to silence compiler warnings
                 */
-       case SOCAM_DATAWIDTH_8:
+       case 8:
                dw = 2;
                bpp = 0;
        }
@@ -1093,11 +1077,11 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
                cicr4 |= CICR4_PCLK_EN;
        if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
                cicr4 |= CICR4_MCLK_EN;
-       if (flags & SOCAM_PCLK_SAMPLE_FALLING)
+       if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
                cicr4 |= CICR4_PCP;
-       if (flags & SOCAM_HSYNC_ACTIVE_LOW)
+       if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
                cicr4 |= CICR4_HSP;
-       if (flags & SOCAM_VSYNC_ACTIVE_LOW)
+       if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
                cicr4 |= CICR4_VSP;
 
        cicr0 = __raw_readl(pcdev->base + CICR0);
@@ -1151,9 +1135,11 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
 
 static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 {
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct pxa_camera_dev *pcdev = ici->priv;
-       unsigned long bus_flags, camera_flags, common_flags;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long bus_flags, common_flags;
        int ret;
        struct pxa_cam *cam = icd->host_priv;
 
@@ -1162,44 +1148,58 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
        if (ret < 0)
                return ret;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-
-       common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
-       if (!common_flags)
-               return -EINVAL;
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg,
+                                                         bus_flags);
+               if (!common_flags) {
+                       dev_warn(icd->parent,
+                                "Flags incompatible: camera 0x%x, host 0x%lx\n",
+                                cfg.flags, bus_flags);
+                       return -EINVAL;
+               }
+       } else if (ret != -ENOIOCTLCMD) {
+               return ret;
+       } else {
+               common_flags = bus_flags;
+       }
 
        pcdev->channels = 1;
 
        /* Make choises, based on platform preferences */
-       if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
                if (pcdev->platform_flags & PXA_CAMERA_HSP)
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
                else
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
        }
 
-       if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
                if (pcdev->platform_flags & PXA_CAMERA_VSP)
-                       common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
                else
-                       common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
        }
 
-       if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
-           (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+       if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
+           (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
                if (pcdev->platform_flags & PXA_CAMERA_PCP)
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
                else
-                       common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+                       common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
        }
 
-       cam->flags = common_flags;
-
-       ret = icd->ops->set_bus_param(icd, common_flags);
-       if (ret < 0)
+       cfg.flags = common_flags;
+       ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
+       if (ret < 0 && ret != -ENOIOCTLCMD) {
+               dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
+                       common_flags, ret);
                return ret;
+       }
+
+       cam->flags = common_flags;
 
        pxa_camera_setup_cicr(icd, common_flags, pixfmt);
 
@@ -1209,17 +1209,31 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 static int pxa_camera_try_bus_param(struct soc_camera_device *icd,
                                    unsigned char buswidth)
 {
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct pxa_camera_dev *pcdev = ici->priv;
-       unsigned long bus_flags, camera_flags;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long bus_flags, common_flags;
        int ret = test_platform_param(pcdev, buswidth, &bus_flags);
 
        if (ret < 0)
                return ret;
 
-       camera_flags = icd->ops->query_bus_param(icd);
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg,
+                                                         bus_flags);
+               if (!common_flags) {
+                       dev_warn(icd->parent,
+                                "Flags incompatible: camera 0x%x, host 0x%lx\n",
+                                cfg.flags, bus_flags);
+                       return -EINVAL;
+               }
+       } else if (ret == -ENOIOCTLCMD) {
+               ret = 0;
+       }
 
-       return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL;
+       return ret;
 }
 
 static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
@@ -1687,6 +1701,12 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
                         "data widths, using default 10 bit\n");
                pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
        }
+       if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8)
+               pcdev->width_flags = 1 << 7;
+       if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9)
+               pcdev->width_flags |= 1 << 8;
+       if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10)
+               pcdev->width_flags |= 1 << 9;
        pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
        if (!pcdev->mclk) {
                dev_warn(&pdev->dev,
index 847ccc0..6afc616 100644 (file)
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
+#include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
 
 #include <media/rj54n1cb0c.h>
 #include <media/soc_camera.h>
-#include <media/soc_mediabus.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ctrls.h>
 
 #define RJ54N1_DEV_CODE                        0x0400
 #define RJ54N1_DEV_CODE2               0x0401
@@ -148,6 +149,7 @@ struct rj54n1_clock_div {
 
 struct rj54n1 {
        struct v4l2_subdev subdev;
+       struct v4l2_ctrl_handler hdl;
        struct rj54n1_clock_div clk_div;
        const struct rj54n1_datafmt *fmt;
        struct v4l2_rect rect;  /* Sensor window */
@@ -499,31 +501,6 @@ static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
        return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80);
 }
 
-static int rj54n1_set_bus_param(struct soc_camera_device *icd,
-                               unsigned long flags)
-{
-       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
-
-       if (flags & SOCAM_PCLK_SAMPLE_RISING)
-               return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
-       else
-               return reg_write(client, RJ54N1_OUT_SIGPO, 0);
-}
-
-static unsigned long rj54n1_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       const unsigned long flags =
-               SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
-               SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
-               SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
-               SOCAM_DATA_ACTIVE_HIGH;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
 static int rj54n1_set_rect(struct i2c_client *client,
                           u16 reg_x, u16 reg_y, u16 reg_xy,
                           u32 width, u32 height)
@@ -1202,134 +1179,51 @@ static int rj54n1_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
-static const struct v4l2_queryctrl rj54n1_controls[] = {
-       {
-               .id             = V4L2_CID_VFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Vertically",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       }, {
-               .id             = V4L2_CID_HFLIP,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Flip Horizontally",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       }, {
-               .id             = V4L2_CID_GAIN,
-               .type           = V4L2_CTRL_TYPE_INTEGER,
-               .name           = "Gain",
-               .minimum        = 0,
-               .maximum        = 127,
-               .step           = 1,
-               .default_value  = 66,
-               .flags          = V4L2_CTRL_FLAG_SLIDER,
-       }, {
-               .id             = V4L2_CID_AUTO_WHITE_BALANCE,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Auto white balance",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 1,
-       },
-};
-
-static struct soc_camera_ops rj54n1_ops = {
-       .set_bus_param          = rj54n1_set_bus_param,
-       .query_bus_param        = rj54n1_query_bus_param,
-       .controls               = rj54n1_controls,
-       .num_controls           = ARRAY_SIZE(rj54n1_controls),
-};
-
-static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+       struct rj54n1 *rj54n1 = container_of(ctrl->handler, struct rj54n1, hdl);
+       struct v4l2_subdev *sd = &rj54n1->subdev;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
        int data;
 
        switch (ctrl->id) {
        case V4L2_CID_VFLIP:
-               data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !(data & 1);
-               break;
-       case V4L2_CID_HFLIP:
-               data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
-               if (data < 0)
-                       return -EIO;
-               ctrl->value = !(data & 2);
-               break;
-       case V4L2_CID_GAIN:
-               data = reg_read(client, RJ54N1_Y_GAIN);
-               if (data < 0)
-                       return -EIO;
-
-               ctrl->value = data / 2;
-               break;
-       case V4L2_CID_AUTO_WHITE_BALANCE:
-               ctrl->value = rj54n1->auto_wb;
-               break;
-       }
-
-       return 0;
-}
-
-static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-       int data;
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct rj54n1 *rj54n1 = to_rj54n1(client);
-       const struct v4l2_queryctrl *qctrl;
-
-       qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id);
-       if (!qctrl)
-               return -EINVAL;
-
-       switch (ctrl->id) {
-       case V4L2_CID_VFLIP:
-               if (ctrl->value)
+               if (ctrl->val)
                        data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
                else
                        data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
                if (data < 0)
                        return -EIO;
-               break;
+               return 0;
        case V4L2_CID_HFLIP:
-               if (ctrl->value)
+               if (ctrl->val)
                        data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
                else
                        data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
                if (data < 0)
                        return -EIO;
-               break;
+               return 0;
        case V4L2_CID_GAIN:
-               if (ctrl->value > qctrl->maximum ||
-                   ctrl->value < qctrl->minimum)
-                       return -EINVAL;
-               else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0)
+               if (reg_write(client, RJ54N1_Y_GAIN, ctrl->val * 2) < 0)
                        return -EIO;
-               break;
+               return 0;
        case V4L2_CID_AUTO_WHITE_BALANCE:
                /* Auto WB area - whole image */
-               if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->value << 7,
+               if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->val << 7,
                            0x80) < 0)
                        return -EIO;
-               rj54n1->auto_wb = ctrl->value;
-               break;
+               rj54n1->auto_wb = ctrl->val;
+               return 0;
        }
 
-       return 0;
+       return -EINVAL;
 }
 
+static const struct v4l2_ctrl_ops rj54n1_ctrl_ops = {
+       .s_ctrl = rj54n1_s_ctrl,
+};
+
 static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
-       .g_ctrl         = rj54n1_g_ctrl,
-       .s_ctrl         = rj54n1_s_ctrl,
        .g_chip_ident   = rj54n1_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register     = rj54n1_g_register,
@@ -1337,6 +1231,36 @@ static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
 #endif
 };
 
+static int rj54n1_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags =
+               V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
+               V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
+static int rj54n1_s_mbus_config(struct v4l2_subdev *sd,
+                               const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
+       if (soc_camera_apply_board_flags(icl, cfg) &
+           V4L2_MBUS_PCLK_SAMPLE_RISING)
+               return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
+       else
+               return reg_write(client, RJ54N1_OUT_SIGPO, 0);
+}
+
 static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
        .s_stream       = rj54n1_s_stream,
        .s_mbus_fmt     = rj54n1_s_fmt,
@@ -1346,6 +1270,8 @@ static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
        .g_crop         = rj54n1_g_crop,
        .s_crop         = rj54n1_s_crop,
        .cropcap        = rj54n1_cropcap,
+       .g_mbus_config  = rj54n1_g_mbus_config,
+       .s_mbus_config  = rj54n1_s_mbus_config,
 };
 
 static struct v4l2_subdev_ops rj54n1_subdev_ops = {
@@ -1357,17 +1283,12 @@ static struct v4l2_subdev_ops rj54n1_subdev_ops = {
  * Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one
  */
-static int rj54n1_video_probe(struct soc_camera_device *icd,
-                             struct i2c_client *client,
+static int rj54n1_video_probe(struct i2c_client *client,
                              struct rj54n1_pdata *priv)
 {
        int data1, data2;
        int ret;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
        /* Read out the chip version register */
        data1 = reg_read(client, RJ54N1_DEV_CODE);
        data2 = reg_read(client, RJ54N1_DEV_CODE2);
@@ -1395,18 +1316,11 @@ static int rj54n1_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 {
        struct rj54n1 *rj54n1;
-       struct soc_camera_device *icd = client->dev.platform_data;
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-       struct soc_camera_link *icl;
        struct rj54n1_pdata *rj54n1_priv;
        int ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "RJ54N1CB0C: missing soc-camera data!\n");
-               return -EINVAL;
-       }
-
-       icl = to_soc_camera_link(icd);
        if (!icl || !icl->priv) {
                dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
                return -EINVAL;
@@ -1425,8 +1339,22 @@ static int rj54n1_probe(struct i2c_client *client,
                return -ENOMEM;
 
        v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
+       v4l2_ctrl_handler_init(&rj54n1->hdl, 4);
+       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
+                       V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
+                       V4L2_CID_HFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
+                       V4L2_CID_GAIN, 0, 127, 1, 66);
+       v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
+                       V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
+       rj54n1->subdev.ctrl_handler = &rj54n1->hdl;
+       if (rj54n1->hdl.error) {
+               int err = rj54n1->hdl.error;
 
-       icd->ops                = &rj54n1_ops;
+               kfree(rj54n1);
+               return err;
+       }
 
        rj54n1->clk_div         = clk_div;
        rj54n1->rect.left       = RJ54N1_COLUMN_SKIP;
@@ -1440,25 +1368,24 @@ static int rj54n1_probe(struct i2c_client *client,
        rj54n1->tgclk_mhz       = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
                (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
 
-       ret = rj54n1_video_probe(icd, client, rj54n1_priv);
+       ret = rj54n1_video_probe(client, rj54n1_priv);
        if (ret < 0) {
-               icd->ops = NULL;
+               v4l2_ctrl_handler_free(&rj54n1->hdl);
                kfree(rj54n1);
                return ret;
        }
-
-       return ret;
+       return v4l2_ctrl_handler_setup(&rj54n1->hdl);
 }
 
 static int rj54n1_remove(struct i2c_client *client)
 {
        struct rj54n1 *rj54n1 = to_rj54n1(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
 
-       icd->ops = NULL;
+       v4l2_device_unregister_subdev(&rj54n1->subdev);
        if (icl->free_bus)
                icl->free_bus(icl);
+       v4l2_ctrl_handler_free(&rj54n1->hdl);
        kfree(rj54n1);
 
        return 0;
diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c
new file mode 100644 (file)
index 0000000..2446736
--- /dev/null
@@ -0,0 +1,1680 @@
+/*
+ * Driver for Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor
+ * with embedded SoC ISP.
+ *
+ * Copyright (C) 2011, Samsung Electronics Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Based on a driver authored by Dongsoo Nathaniel Kim.
+ * Copyright (C) 2009, Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/media.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-mediabus.h>
+#include <media/s5k6aa.h>
+
+static int debug;
+module_param(debug, int, 0644);
+
+#define DRIVER_NAME                    "S5K6AA"
+
+/* The token to indicate array termination */
+#define S5K6AA_TERM                    0xffff
+#define S5K6AA_OUT_WIDTH_DEF           640
+#define S5K6AA_OUT_HEIGHT_DEF          480
+#define S5K6AA_WIN_WIDTH_MAX           1280
+#define S5K6AA_WIN_HEIGHT_MAX          1024
+#define S5K6AA_WIN_WIDTH_MIN           8
+#define S5K6AA_WIN_HEIGHT_MIN          8
+
+/*
+ * H/W register Interface (0xD0000000 - 0xD0000FFF)
+ */
+#define AHB_MSB_ADDR_PTR               0xfcfc
+#define GEN_REG_OFFSH                  0xd000
+#define REG_CMDWR_ADDRH                        0x0028
+#define REG_CMDWR_ADDRL                        0x002a
+#define REG_CMDRD_ADDRH                        0x002c
+#define REG_CMDRD_ADDRL                        0x002e
+#define REG_CMDBUF0_ADDR               0x0f12
+#define REG_CMDBUF1_ADDR               0x0f10
+
+/*
+ * Host S/W Register interface (0x70000000 - 0x70002000)
+ * The value of the two most significant address bytes is 0x7000,
+ * (HOST_SWIF_OFFS_H). The register addresses below specify 2 LSBs.
+ */
+#define HOST_SWIF_OFFSH                        0x7000
+
+/* Initialization parameters */
+/* Master clock frequency in KHz */
+#define REG_I_INCLK_FREQ_L             0x01b8
+#define REG_I_INCLK_FREQ_H             0x01ba
+#define  MIN_MCLK_FREQ_KHZ             6000U
+#define  MAX_MCLK_FREQ_KHZ             27000U
+#define REG_I_USE_NPVI_CLOCKS          0x01c6
+#define REG_I_USE_NMIPI_CLOCKS         0x01c8
+
+/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
+#define REG_I_OPCLK_4KHZ(n)            ((n) * 6 + 0x01cc)
+#define REG_I_MIN_OUTRATE_4KHZ(n)      ((n) * 6 + 0x01ce)
+#define REG_I_MAX_OUTRATE_4KHZ(n)      ((n) * 6 + 0x01d0)
+#define  SYS_PLL_OUT_FREQ              (48000000 / 4000)
+#define  PCLK_FREQ_MIN                 (24000000 / 4000)
+#define  PCLK_FREQ_MAX                 (48000000 / 4000)
+#define REG_I_INIT_PARAMS_UPDATED      0x01e0
+#define REG_I_ERROR_INFO               0x01e2
+
+/* General purpose parameters */
+#define REG_USER_BRIGHTNESS            0x01e4
+#define REG_USER_CONTRAST              0x01e6
+#define REG_USER_SATURATION            0x01e8
+#define REG_USER_SHARPBLUR             0x01ea
+
+#define REG_G_SPEC_EFFECTS             0x01ee
+#define REG_G_ENABLE_PREV              0x01f0
+#define REG_G_ENABLE_PREV_CHG          0x01f2
+#define REG_G_NEW_CFG_SYNC             0x01f8
+#define REG_G_PREVZOOM_IN_WIDTH                0x020a
+#define REG_G_PREVZOOM_IN_HEIGHT       0x020c
+#define REG_G_PREVZOOM_IN_XOFFS                0x020e
+#define REG_G_PREVZOOM_IN_YOFFS                0x0210
+#define REG_G_INPUTS_CHANGE_REQ                0x021a
+#define REG_G_ACTIVE_PREV_CFG          0x021c
+#define REG_G_PREV_CFG_CHG             0x021e
+#define REG_G_PREV_OPEN_AFTER_CH       0x0220
+#define REG_G_PREV_CFG_ERROR           0x0222
+
+/* Preview control section. n = 0...4. */
+#define PREG(n, x)                     ((n) * 0x26 + x)
+#define REG_P_OUT_WIDTH(n)             PREG(n, 0x0242)
+#define REG_P_OUT_HEIGHT(n)            PREG(n, 0x0244)
+#define REG_P_FMT(n)                   PREG(n, 0x0246)
+#define REG_P_MAX_OUT_RATE(n)          PREG(n, 0x0248)
+#define REG_P_MIN_OUT_RATE(n)          PREG(n, 0x024a)
+#define REG_P_PVI_MASK(n)              PREG(n, 0x024c)
+#define REG_P_CLK_INDEX(n)             PREG(n, 0x024e)
+#define REG_P_FR_RATE_TYPE(n)          PREG(n, 0x0250)
+#define  FR_RATE_DYNAMIC               0
+#define  FR_RATE_FIXED                 1
+#define  FR_RATE_FIXED_ACCURATE                2
+#define REG_P_FR_RATE_Q_TYPE(n)                PREG(n, 0x0252)
+#define  FR_RATE_Q_BEST_FRRATE         1 /* Binning enabled */
+#define  FR_RATE_Q_BEST_QUALITY                2 /* Binning disabled */
+/* Frame period in 0.1 ms units */
+#define REG_P_MAX_FR_TIME(n)           PREG(n, 0x0254)
+#define REG_P_MIN_FR_TIME(n)           PREG(n, 0x0256)
+/* Conversion to REG_P_[MAX/MIN]_FR_TIME value; __t: time in us */
+#define  US_TO_FR_TIME(__t)            ((__t) / 100)
+#define  S5K6AA_MIN_FR_TIME            33300  /* us */
+#define  S5K6AA_MAX_FR_TIME            650000 /* us */
+#define  S5K6AA_MAX_HIGHRES_FR_TIME    666    /* x100 us */
+/* The below 5 registers are for "device correction" values */
+#define REG_P_COLORTEMP(n)             PREG(n, 0x025e)
+#define REG_P_PREV_MIRROR(n)           PREG(n, 0x0262)
+
+/* Extended image property controls */
+/* Exposure time in 10 us units */
+#define REG_SF_USR_EXPOSURE_L          0x03c6
+#define REG_SF_USR_EXPOSURE_H          0x03c8
+#define REG_SF_USR_EXPOSURE_CHG                0x03ca
+#define REG_SF_USR_TOT_GAIN            0x03cc
+#define REG_SF_USR_TOT_GAIN_CHG                0x03ce
+#define REG_SF_RGAIN                   0x03d0
+#define REG_SF_RGAIN_CHG               0x03d2
+#define REG_SF_GGAIN                   0x03d4
+#define REG_SF_GGAIN_CHG               0x03d6
+#define REG_SF_BGAIN                   0x03d8
+#define REG_SF_BGAIN_CHG               0x03da
+#define REG_SF_FLICKER_QUANT           0x03dc
+#define REG_SF_FLICKER_QUANT_CHG       0x03de
+
+/* Output interface (parallel/MIPI) setup */
+#define REG_OIF_EN_MIPI_LANES          0x03fa
+#define REG_OIF_EN_PACKETS             0x03fc
+#define REG_OIF_CFG_CHG                        0x03fe
+
+/* Auto-algorithms enable mask */
+#define REG_DBG_AUTOALG_EN             0x0400
+#define  AALG_ALL_EN_MASK              (1 << 0)
+#define  AALG_AE_EN_MASK               (1 << 1)
+#define  AALG_DIVLEI_EN_MASK           (1 << 2)
+#define  AALG_WB_EN_MASK               (1 << 3)
+#define  AALG_FLICKER_EN_MASK          (1 << 5)
+#define  AALG_FIT_EN_MASK              (1 << 6)
+#define  AALG_WRHW_EN_MASK             (1 << 7)
+
+/* Firmware revision information */
+#define REG_FW_APIVER                  0x012e
+#define  S5K6AAFX_FW_APIVER            0x0001
+#define REG_FW_REVISION                        0x0130
+
+/* For now we use only one user configuration register set */
+#define S5K6AA_MAX_PRESETS             1
+
+static const char * const s5k6aa_supply_names[] = {
+       "vdd_core",     /* Digital core supply 1.5V (1.4V to 1.6V) */
+       "vdda",         /* Analog power supply 2.8V (2.6V to 3.0V) */
+       "vdd_reg",      /* Regulator input power 1.8V (1.7V to 1.9V)
+                          or 2.8V (2.6V to 3.0) */
+       "vddio",        /* I/O supply 1.8V (1.65V to 1.95V)
+                          or 2.8V (2.5V to 3.1V) */
+};
+#define S5K6AA_NUM_SUPPLIES ARRAY_SIZE(s5k6aa_supply_names)
+
+enum s5k6aa_gpio_id {
+       STBY,
+       RST,
+       GPIO_NUM,
+};
+
+struct s5k6aa_regval {
+       u16 addr;
+       u16 val;
+};
+
+struct s5k6aa_pixfmt {
+       enum v4l2_mbus_pixelcode code;
+       u32 colorspace;
+       /* REG_P_FMT(x) register value */
+       u16 reg_p_fmt;
+};
+
+struct s5k6aa_preset {
+       /* output pixel format and resolution */
+       struct v4l2_mbus_framefmt mbus_fmt;
+       u8 clk_id;
+       u8 index;
+};
+
+struct s5k6aa_ctrls {
+       struct v4l2_ctrl_handler handler;
+       /* Auto / manual white balance cluster */
+       struct v4l2_ctrl *awb;
+       struct v4l2_ctrl *gain_red;
+       struct v4l2_ctrl *gain_blue;
+       struct v4l2_ctrl *gain_green;
+       /* Mirror cluster */
+       struct v4l2_ctrl *hflip;
+       struct v4l2_ctrl *vflip;
+       /* Auto exposure / manual exposure and gain cluster */
+       struct v4l2_ctrl *auto_exp;
+       struct v4l2_ctrl *exposure;
+       struct v4l2_ctrl *gain;
+};
+
+struct s5k6aa_interval {
+       u16 reg_fr_time;
+       struct v4l2_fract interval;
+       /* Maximum rectangle for the interval */
+       struct v4l2_frmsize_discrete size;
+};
+
+struct s5k6aa {
+       struct v4l2_subdev sd;
+       struct media_pad pad;
+
+       enum v4l2_mbus_type bus_type;
+       u8 mipi_lanes;
+
+       int (*s_power)(int enable);
+       struct regulator_bulk_data supplies[S5K6AA_NUM_SUPPLIES];
+       struct s5k6aa_gpio gpio[GPIO_NUM];
+
+       /* external master clock frequency */
+       unsigned long mclk_frequency;
+       /* ISP internal master clock frequency */
+       u16 clk_fop;
+       /* output pixel clock frequency range */
+       u16 pclk_fmin;
+       u16 pclk_fmax;
+
+       unsigned int inv_hflip:1;
+       unsigned int inv_vflip:1;
+
+       /* protects the struct members below */
+       struct mutex lock;
+
+       /* sensor matrix scan window */
+       struct v4l2_rect ccd_rect;
+
+       struct s5k6aa_ctrls ctrls;
+       struct s5k6aa_preset presets[S5K6AA_MAX_PRESETS];
+       struct s5k6aa_preset *preset;
+       const struct s5k6aa_interval *fiv;
+
+       unsigned int streaming:1;
+       unsigned int apply_cfg:1;
+       unsigned int apply_crop:1;
+       unsigned int power;
+};
+
+static struct s5k6aa_regval s5k6aa_analog_config[] = {
+       /* Analog settings */
+       { 0x112a, 0x0000 }, { 0x1132, 0x0000 },
+       { 0x113e, 0x0000 }, { 0x115c, 0x0000 },
+       { 0x1164, 0x0000 }, { 0x1174, 0x0000 },
+       { 0x1178, 0x0000 }, { 0x077a, 0x0000 },
+       { 0x077c, 0x0000 }, { 0x077e, 0x0000 },
+       { 0x0780, 0x0000 }, { 0x0782, 0x0000 },
+       { 0x0784, 0x0000 }, { 0x0786, 0x0000 },
+       { 0x0788, 0x0000 }, { 0x07a2, 0x0000 },
+       { 0x07a4, 0x0000 }, { 0x07a6, 0x0000 },
+       { 0x07a8, 0x0000 }, { 0x07b6, 0x0000 },
+       { 0x07b8, 0x0002 }, { 0x07ba, 0x0004 },
+       { 0x07bc, 0x0004 }, { 0x07be, 0x0005 },
+       { 0x07c0, 0x0005 }, { S5K6AA_TERM, 0 },
+};
+
+/* TODO: Add RGB888 and Bayer format */
+static const struct s5k6aa_pixfmt s5k6aa_formats[] = {
+       { V4L2_MBUS_FMT_YUYV8_2X8,      V4L2_COLORSPACE_JPEG,   5 },
+       /* range 16-240 */
+       { V4L2_MBUS_FMT_YUYV8_2X8,      V4L2_COLORSPACE_REC709, 6 },
+       { V4L2_MBUS_FMT_RGB565_2X8_BE,  V4L2_COLORSPACE_JPEG,   0 },
+};
+
+static const struct s5k6aa_interval s5k6aa_intervals[] = {
+       { 1000, {10000, 1000000}, {1280, 1024} }, /* 10 fps */
+       { 666,  {15000, 1000000}, {1280, 1024} }, /* 15 fps */
+       { 500,  {20000, 1000000}, {1280, 720} },  /* 20 fps */
+       { 400,  {25000, 1000000}, {640, 480} },   /* 25 fps */
+       { 333,  {33300, 1000000}, {640, 480} },   /* 30 fps */
+};
+
+#define S5K6AA_INTERVAL_DEF_INDEX 1 /* 15 fps */
+
+static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
+{
+       return &container_of(ctrl->handler, struct s5k6aa, ctrls.handler)->sd;
+}
+
+static inline struct s5k6aa *to_s5k6aa(struct v4l2_subdev *sd)
+{
+       return container_of(sd, struct s5k6aa, sd);
+}
+
+/* Set initial values for all preview presets */
+static void s5k6aa_presets_data_init(struct s5k6aa *s5k6aa)
+{
+       struct s5k6aa_preset *preset = &s5k6aa->presets[0];
+       int i;
+
+       for (i = 0; i < S5K6AA_MAX_PRESETS; i++) {
+               preset->mbus_fmt.width  = S5K6AA_OUT_WIDTH_DEF;
+               preset->mbus_fmt.height = S5K6AA_OUT_HEIGHT_DEF;
+               preset->mbus_fmt.code   = s5k6aa_formats[0].code;
+               preset->index           = i;
+               preset->clk_id          = 0;
+               preset++;
+       }
+
+       s5k6aa->fiv = &s5k6aa_intervals[S5K6AA_INTERVAL_DEF_INDEX];
+       s5k6aa->preset = &s5k6aa->presets[0];
+}
+
+static int s5k6aa_i2c_read(struct i2c_client *client, u16 addr, u16 *val)
+{
+       u8 wbuf[2] = {addr >> 8, addr & 0xFF};
+       struct i2c_msg msg[2];
+       u8 rbuf[2];
+       int ret;
+
+       msg[0].addr = client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 2;
+       msg[0].buf = wbuf;
+
+       msg[1].addr = client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len = 2;
+       msg[1].buf = rbuf;
+
+       ret = i2c_transfer(client->adapter, msg, 2);
+       *val = be16_to_cpu(*((u16 *)rbuf));
+
+       v4l2_dbg(3, debug, client, "i2c_read: 0x%04X : 0x%04x\n", addr, *val);
+
+       return ret == 2 ? 0 : ret;
+}
+
+static int s5k6aa_i2c_write(struct i2c_client *client, u16 addr, u16 val)
+{
+       u8 buf[4] = {addr >> 8, addr & 0xFF, val >> 8, val & 0xFF};
+
+       int ret = i2c_master_send(client, buf, 4);
+       v4l2_dbg(3, debug, client, "i2c_write: 0x%04X : 0x%04x\n", addr, val);
+
+       return ret == 4 ? 0 : ret;
+}
+
+/* The command register write, assumes Command_Wr_addH = 0x7000. */
+static int s5k6aa_write(struct i2c_client *c, u16 addr, u16 val)
+{
+       int ret = s5k6aa_i2c_write(c, REG_CMDWR_ADDRL, addr);
+       if (ret)
+               return ret;
+       return s5k6aa_i2c_write(c, REG_CMDBUF0_ADDR, val);
+}
+
+/* The command register read, assumes Command_Rd_addH = 0x7000. */
+static int s5k6aa_read(struct i2c_client *client, u16 addr, u16 *val)
+{
+       int ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRL, addr);
+       if (ret)
+               return ret;
+       return s5k6aa_i2c_read(client, REG_CMDBUF0_ADDR, val);
+}
+
+static int s5k6aa_write_array(struct v4l2_subdev *sd,
+                             const struct s5k6aa_regval *msg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       u16 addr_incr = 0;
+       int ret = 0;
+
+       while (msg->addr != S5K6AA_TERM) {
+               if (addr_incr != 2)
+                       ret = s5k6aa_i2c_write(client, REG_CMDWR_ADDRL,
+                                              msg->addr);
+               if (ret)
+                       break;
+               ret = s5k6aa_i2c_write(client, REG_CMDBUF0_ADDR, msg->val);
+               if (ret)
+                       break;
+               /* Assume that msg->addr is always less than 0xfffc */
+               addr_incr = (msg + 1)->addr - msg->addr;
+               msg++;
+       }
+
+       return ret;
+}
+
+/* Configure the AHB high address bytes for GTG registers access */
+static int s5k6aa_set_ahb_address(struct i2c_client *client)
+{
+       int ret = s5k6aa_i2c_write(client, AHB_MSB_ADDR_PTR, GEN_REG_OFFSH);
+       if (ret)
+               return ret;
+       ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRH, HOST_SWIF_OFFSH);
+       if (ret)
+               return ret;
+       return s5k6aa_i2c_write(client, REG_CMDWR_ADDRH, HOST_SWIF_OFFSH);
+}
+
+/**
+ * s5k6aa_configure_pixel_clock - apply ISP main clock/PLL configuration
+ *
+ * Configure the internal ISP PLL for the required output frequency.
+ * Locking: called with s5k6aa.lock mutex held.
+ */
+static int s5k6aa_configure_pixel_clocks(struct s5k6aa *s5k6aa)
+{
+       struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
+       unsigned long fmclk = s5k6aa->mclk_frequency / 1000;
+       u16 status;
+       int ret;
+
+       if (WARN(fmclk < MIN_MCLK_FREQ_KHZ || fmclk > MAX_MCLK_FREQ_KHZ,
+                "Invalid clock frequency: %ld\n", fmclk))
+               return -EINVAL;
+
+       s5k6aa->pclk_fmin = PCLK_FREQ_MIN;
+       s5k6aa->pclk_fmax = PCLK_FREQ_MAX;
+       s5k6aa->clk_fop = SYS_PLL_OUT_FREQ;
+
+       /* External input clock frequency in kHz */
+       ret = s5k6aa_write(c, REG_I_INCLK_FREQ_H, fmclk >> 16);
+       if (!ret)
+               ret = s5k6aa_write(c, REG_I_INCLK_FREQ_L, fmclk & 0xFFFF);
+       if (!ret)
+               ret = s5k6aa_write(c, REG_I_USE_NPVI_CLOCKS, 1);
+       /* Internal PLL frequency */
+       if (!ret)
+               ret = s5k6aa_write(c, REG_I_OPCLK_4KHZ(0), s5k6aa->clk_fop);
+       if (!ret)
+               ret = s5k6aa_write(c, REG_I_MIN_OUTRATE_4KHZ(0),
+                                  s5k6aa->pclk_fmin);
+       if (!ret)
+               ret = s5k6aa_write(c, REG_I_MAX_OUTRATE_4KHZ(0),
+                                  s5k6aa->pclk_fmax);
+       if (!ret)
+               ret = s5k6aa_write(c, REG_I_INIT_PARAMS_UPDATED, 1);
+       if (!ret)
+               ret = s5k6aa_read(c, REG_I_ERROR_INFO, &status);
+
+       return ret ? ret : (status ? -EINVAL : 0);
+}
+
+/* Set horizontal and vertical image flipping */
+static int s5k6aa_set_mirror(struct s5k6aa *s5k6aa, int horiz_flip)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+       int index = s5k6aa->preset->index;
+
+       unsigned int vflip = s5k6aa->ctrls.vflip->val ^ s5k6aa->inv_vflip;
+       unsigned int flip = (horiz_flip ^ s5k6aa->inv_hflip) | (vflip << 1);
+
+       return s5k6aa_write(client, REG_P_PREV_MIRROR(index), flip);
+}
+
+/* Configure auto/manual white balance and R/G/B gains */
+static int s5k6aa_set_awb(struct s5k6aa *s5k6aa, int awb)
+{
+       struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
+       struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
+       u16 reg;
+
+       int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &reg);
+
+       if (!ret && !awb) {
+               ret = s5k6aa_write(c, REG_SF_RGAIN, ctrls->gain_red->val);
+               if (!ret)
+                       ret = s5k6aa_write(c, REG_SF_RGAIN_CHG, 1);
+               if (ret)
+                       return ret;
+
+               ret = s5k6aa_write(c, REG_SF_GGAIN, ctrls->gain_green->val);
+               if (!ret)
+                       ret = s5k6aa_write(c, REG_SF_GGAIN_CHG, 1);
+               if (ret)
+                       return ret;
+
+               ret = s5k6aa_write(c, REG_SF_BGAIN, ctrls->gain_blue->val);
+               if (!ret)
+                       ret = s5k6aa_write(c, REG_SF_BGAIN_CHG, 1);
+       }
+       if (!ret) {
+               reg = awb ? reg | AALG_WB_EN_MASK : reg & ~AALG_WB_EN_MASK;
+               ret = s5k6aa_write(c, REG_DBG_AUTOALG_EN, reg);
+       }
+
+       return ret;
+}
+
+/* Program FW with exposure time, 'exposure' in us units */
+static int s5k6aa_set_user_exposure(struct i2c_client *client, int exposure)
+{
+       unsigned int time = exposure / 10;
+
+       int ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_L, time & 0xffff);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_H, time >> 16);
+       if (ret)
+               return ret;
+       return s5k6aa_write(client, REG_SF_USR_EXPOSURE_CHG, 1);
+}
+
+static int s5k6aa_set_user_gain(struct i2c_client *client, int gain)
+{
+       int ret = s5k6aa_write(client, REG_SF_USR_TOT_GAIN, gain);
+       if (ret)
+               return ret;
+       return s5k6aa_write(client, REG_SF_USR_TOT_GAIN_CHG, 1);
+}
+
+/* Set auto/manual exposure and total gain */
+static int s5k6aa_set_auto_exposure(struct s5k6aa *s5k6aa, int value)
+{
+       struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
+       unsigned int exp_time = s5k6aa->ctrls.exposure->val;
+       u16 auto_alg;
+
+       int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &auto_alg);
+       if (ret)
+               return ret;
+
+       v4l2_dbg(1, debug, c, "man_exp: %d, auto_exp: %d, a_alg: 0x%x\n",
+                exp_time, value, auto_alg);
+
+       if (value == V4L2_EXPOSURE_AUTO) {
+               auto_alg |= AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK;
+       } else {
+               ret = s5k6aa_set_user_exposure(c, exp_time);
+               if (ret)
+                       return ret;
+               ret = s5k6aa_set_user_gain(c, s5k6aa->ctrls.gain->val);
+               if (ret)
+                       return ret;
+               auto_alg &= ~(AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK);
+       }
+
+       return s5k6aa_write(c, REG_DBG_AUTOALG_EN, auto_alg);
+}
+
+static int s5k6aa_set_anti_flicker(struct s5k6aa *s5k6aa, int value)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+       u16 auto_alg;
+       int ret;
+
+       ret = s5k6aa_read(client, REG_DBG_AUTOALG_EN, &auto_alg);
+       if (ret)
+               return ret;
+
+       if (value == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
+               auto_alg |= AALG_FLICKER_EN_MASK;
+       } else {
+               auto_alg &= ~AALG_FLICKER_EN_MASK;
+               /* The V4L2_CID_LINE_FREQUENCY control values match
+                * the register values */
+               ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT, value);
+               if (ret)
+                       return ret;
+               ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT_CHG, 1);
+               if (ret)
+                       return ret;
+       }
+
+       return s5k6aa_write(client, REG_DBG_AUTOALG_EN, auto_alg);
+}
+
+static int s5k6aa_set_colorfx(struct s5k6aa *s5k6aa, int val)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+       static const struct v4l2_control colorfx[] = {
+               { V4L2_COLORFX_NONE,     0 },
+               { V4L2_COLORFX_BW,       1 },
+               { V4L2_COLORFX_NEGATIVE, 2 },
+               { V4L2_COLORFX_SEPIA,    3 },
+               { V4L2_COLORFX_SKY_BLUE, 4 },
+               { V4L2_COLORFX_SKETCH,   5 },
+       };
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(colorfx); i++) {
+               if (colorfx[i].id == val)
+                       return s5k6aa_write(client, REG_G_SPEC_EFFECTS,
+                                           colorfx[i].value);
+       }
+       return -EINVAL;
+}
+
+static int s5k6aa_preview_config_status(struct i2c_client *client)
+{
+       u16 error = 0;
+       int ret = s5k6aa_read(client, REG_G_PREV_CFG_ERROR, &error);
+
+       v4l2_dbg(1, debug, client, "error: 0x%x (%d)\n", error, ret);
+       return ret ? ret : (error ? -EINVAL : 0);
+}
+
+static int s5k6aa_get_pixfmt_index(struct s5k6aa *s5k6aa,
+                                  struct v4l2_mbus_framefmt *mf)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(s5k6aa_formats); i++)
+               if (mf->colorspace == s5k6aa_formats[i].colorspace &&
+                   mf->code == s5k6aa_formats[i].code)
+                       return i;
+       return 0;
+}
+
+static int s5k6aa_set_output_framefmt(struct s5k6aa *s5k6aa,
+                                     struct s5k6aa_preset *preset)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+       int fmt_index = s5k6aa_get_pixfmt_index(s5k6aa, &preset->mbus_fmt);
+       int ret;
+
+       ret = s5k6aa_write(client, REG_P_OUT_WIDTH(preset->index),
+                          preset->mbus_fmt.width);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_P_OUT_HEIGHT(preset->index),
+                                  preset->mbus_fmt.height);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_P_FMT(preset->index),
+                                  s5k6aa_formats[fmt_index].reg_p_fmt);
+       return ret;
+}
+
+static int s5k6aa_set_input_params(struct s5k6aa *s5k6aa)
+{
+       struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
+       struct v4l2_rect *r = &s5k6aa->ccd_rect;
+       int ret;
+
+       ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_WIDTH, r->width);
+       if (!ret)
+               ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_HEIGHT, r->height);
+       if (!ret)
+               ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_XOFFS, r->left);
+       if (!ret)
+               ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_YOFFS, r->top);
+       if (!ret)
+               ret = s5k6aa_write(c, REG_G_INPUTS_CHANGE_REQ, 1);
+       if (!ret)
+               s5k6aa->apply_crop = 0;
+
+       return ret;
+}
+
+/**
+ * s5k6aa_configure_video_bus - configure the video output interface
+ * @bus_type: video bus type: parallel or MIPI-CSI
+ * @nlanes: number of MIPI lanes to be used (MIPI-CSI only)
+ *
+ * Note: Only parallel bus operation has been tested.
+ */
+static int s5k6aa_configure_video_bus(struct s5k6aa *s5k6aa,
+                                     enum v4l2_mbus_type bus_type, int nlanes)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+       u16 cfg = 0;
+       int ret;
+
+       /*
+        * TODO: The sensor is supposed to support BT.601 and BT.656
+        * but there is nothing indicating how to switch between both
+        * in the datasheet. For now default BT.601 interface is assumed.
+        */
+       if (bus_type == V4L2_MBUS_CSI2)
+               cfg = nlanes;
+       else if (bus_type != V4L2_MBUS_PARALLEL)
+               return -EINVAL;
+
+       ret = s5k6aa_write(client, REG_OIF_EN_MIPI_LANES, cfg);
+       if (ret)
+               return ret;
+       return s5k6aa_write(client, REG_OIF_CFG_CHG, 1);
+}
+
+/* This function should be called when switching to new user configuration set*/
+static int s5k6aa_new_config_sync(struct i2c_client *client, int timeout,
+                                 int cid)
+{
+       unsigned long end = jiffies + msecs_to_jiffies(timeout);
+       u16 reg = 1;
+       int ret;
+
+       ret = s5k6aa_write(client, REG_G_ACTIVE_PREV_CFG, cid);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_G_NEW_CFG_SYNC, 1);
+       if (timeout == 0)
+               return ret;
+
+       while (ret >= 0 && time_is_after_jiffies(end)) {
+               ret = s5k6aa_read(client, REG_G_NEW_CFG_SYNC, &reg);
+               if (!reg)
+                       return 0;
+               usleep_range(1000, 5000);
+       }
+       return ret ? ret : -ETIMEDOUT;
+}
+
+/**
+ * s5k6aa_set_prev_config - write user preview register set
+ *
+ * Configure output resolution and color fromat, pixel clock
+ * frequency range, device frame rate type and frame period range.
+ */
+static int s5k6aa_set_prev_config(struct s5k6aa *s5k6aa,
+                                 struct s5k6aa_preset *preset)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+       int idx = preset->index;
+       u16 frame_rate_q;
+       int ret;
+
+       if (s5k6aa->fiv->reg_fr_time >= S5K6AA_MAX_HIGHRES_FR_TIME)
+               frame_rate_q = FR_RATE_Q_BEST_FRRATE;
+       else
+               frame_rate_q = FR_RATE_Q_BEST_QUALITY;
+
+       ret = s5k6aa_set_output_framefmt(s5k6aa, preset);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_P_MAX_OUT_RATE(idx),
+                                  s5k6aa->pclk_fmax);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_P_MIN_OUT_RATE(idx),
+                                  s5k6aa->pclk_fmin);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_P_CLK_INDEX(idx),
+                                  preset->clk_id);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_P_FR_RATE_TYPE(idx),
+                                  FR_RATE_DYNAMIC);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_P_FR_RATE_Q_TYPE(idx),
+                                  frame_rate_q);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_P_MAX_FR_TIME(idx),
+                                  s5k6aa->fiv->reg_fr_time + 33);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_P_MIN_FR_TIME(idx),
+                                  s5k6aa->fiv->reg_fr_time - 33);
+       if (!ret)
+               ret = s5k6aa_new_config_sync(client, 250, idx);
+       if (!ret)
+               ret = s5k6aa_preview_config_status(client);
+       if (!ret)
+               s5k6aa->apply_cfg = 0;
+
+       v4l2_dbg(1, debug, client, "Frame interval: %d +/- 3.3ms. (%d)\n",
+                s5k6aa->fiv->reg_fr_time, ret);
+       return ret;
+}
+
+/**
+ * s5k6aa_initialize_isp - basic ISP MCU initialization
+ *
+ * Configure AHB addresses for registers read/write; configure PLLs for
+ * required output pixel clock. The ISP power supply needs to be already
+ * enabled, with an optional H/W reset.
+ * Locking: called with s5k6aa.lock mutex held.
+ */
+static int s5k6aa_initialize_isp(struct v4l2_subdev *sd)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       int ret;
+
+       s5k6aa->apply_crop = 1;
+       s5k6aa->apply_cfg = 1;
+       msleep(100);
+
+       ret = s5k6aa_set_ahb_address(client);
+       if (ret)
+               return ret;
+       ret = s5k6aa_configure_video_bus(s5k6aa, s5k6aa->bus_type,
+                                        s5k6aa->mipi_lanes);
+       if (ret)
+               return ret;
+       ret = s5k6aa_write_array(sd, s5k6aa_analog_config);
+       if (ret)
+               return ret;
+       msleep(20);
+
+       return s5k6aa_configure_pixel_clocks(s5k6aa);
+}
+
+static int s5k6aa_gpio_set_value(struct s5k6aa *priv, int id, u32 val)
+{
+       if (!gpio_is_valid(priv->gpio[id].gpio))
+               return 0;
+       gpio_set_value(priv->gpio[id].gpio, !!val);
+       return 1;
+}
+
+static int s5k6aa_gpio_assert(struct s5k6aa *priv, int id)
+{
+       return s5k6aa_gpio_set_value(priv, id, priv->gpio[id].level);
+}
+
+static int s5k6aa_gpio_deassert(struct s5k6aa *priv, int id)
+{
+       return s5k6aa_gpio_set_value(priv, id, !priv->gpio[id].level);
+}
+
+static int __s5k6aa_power_on(struct s5k6aa *s5k6aa)
+{
+       int ret;
+
+       ret = regulator_bulk_enable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
+       if (ret)
+               return ret;
+       if (s5k6aa_gpio_deassert(s5k6aa, STBY))
+               usleep_range(150, 200);
+
+       if (s5k6aa->s_power)
+               ret = s5k6aa->s_power(1);
+       usleep_range(4000, 4000);
+
+       if (s5k6aa_gpio_deassert(s5k6aa, RST))
+               msleep(20);
+
+       return ret;
+}
+
+static int __s5k6aa_power_off(struct s5k6aa *s5k6aa)
+{
+       int ret;
+
+       if (s5k6aa_gpio_assert(s5k6aa, RST))
+               usleep_range(100, 150);
+
+       if (s5k6aa->s_power) {
+               ret = s5k6aa->s_power(0);
+               if (ret)
+                       return ret;
+       }
+       if (s5k6aa_gpio_assert(s5k6aa, STBY))
+               usleep_range(50, 100);
+       s5k6aa->streaming = 0;
+
+       return regulator_bulk_disable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
+}
+
+/*
+ * V4L2 subdev core and video operations
+ */
+static int s5k6aa_set_power(struct v4l2_subdev *sd, int on)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       int ret = 0;
+
+       mutex_lock(&s5k6aa->lock);
+
+       if (!on == s5k6aa->power) {
+               if (on) {
+                       ret = __s5k6aa_power_on(s5k6aa);
+                       if (!ret)
+                               ret = s5k6aa_initialize_isp(sd);
+               } else {
+                       ret = __s5k6aa_power_off(s5k6aa);
+               }
+
+               if (!ret)
+                       s5k6aa->power += on ? 1 : -1;
+       }
+
+       mutex_unlock(&s5k6aa->lock);
+
+       if (!on || ret || s5k6aa->power != 1)
+               return ret;
+
+       return v4l2_ctrl_handler_setup(sd->ctrl_handler);
+}
+
+static int __s5k6aa_stream(struct s5k6aa *s5k6aa, int enable)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+       int ret = 0;
+
+       ret = s5k6aa_write(client, REG_G_ENABLE_PREV, enable);
+       if (!ret)
+               ret = s5k6aa_write(client, REG_G_ENABLE_PREV_CHG, 1);
+       if (!ret)
+               s5k6aa->streaming = enable;
+
+       return ret;
+}
+
+static int s5k6aa_s_stream(struct v4l2_subdev *sd, int on)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       int ret = 0;
+
+       mutex_lock(&s5k6aa->lock);
+
+       if (s5k6aa->streaming == !on) {
+               if (!ret && s5k6aa->apply_cfg)
+                       ret = s5k6aa_set_prev_config(s5k6aa, s5k6aa->preset);
+               if (s5k6aa->apply_crop)
+                       ret = s5k6aa_set_input_params(s5k6aa);
+               if (!ret)
+                       ret = __s5k6aa_stream(s5k6aa, !!on);
+       }
+       mutex_unlock(&s5k6aa->lock);
+
+       return ret;
+}
+
+static int s5k6aa_g_frame_interval(struct v4l2_subdev *sd,
+                                  struct v4l2_subdev_frame_interval *fi)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+
+       mutex_lock(&s5k6aa->lock);
+       fi->interval = s5k6aa->fiv->interval;
+       mutex_unlock(&s5k6aa->lock);
+
+       return 0;
+}
+
+static int __s5k6aa_set_frame_interval(struct s5k6aa *s5k6aa,
+                                      struct v4l2_subdev_frame_interval *fi)
+{
+       struct v4l2_mbus_framefmt *mbus_fmt = &s5k6aa->preset->mbus_fmt;
+       const struct s5k6aa_interval *fiv = &s5k6aa_intervals[0];
+       unsigned int err, min_err = UINT_MAX;
+       unsigned int i, fr_time;
+
+       if (fi->interval.denominator == 0)
+               return -EINVAL;
+
+       fr_time = fi->interval.numerator * 10000 / fi->interval.denominator;
+
+       for (i = 0; i < ARRAY_SIZE(s5k6aa_intervals); i++) {
+               const struct s5k6aa_interval *iv = &s5k6aa_intervals[i];
+
+               if (mbus_fmt->width > iv->size.width ||
+                   mbus_fmt->height > iv->size.height)
+                       continue;
+
+               err = abs(iv->reg_fr_time - fr_time);
+               if (err < min_err) {
+                       fiv = iv;
+                       min_err = err;
+               }
+       }
+       s5k6aa->fiv = fiv;
+
+       v4l2_dbg(1, debug, &s5k6aa->sd, "Changed frame interval to %d us\n",
+                fiv->reg_fr_time * 100);
+       return 0;
+}
+
+static int s5k6aa_s_frame_interval(struct v4l2_subdev *sd,
+                                  struct v4l2_subdev_frame_interval *fi)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       int ret;
+
+       v4l2_dbg(1, debug, sd, "Setting %d/%d frame interval\n",
+                fi->interval.numerator, fi->interval.denominator);
+
+       mutex_lock(&s5k6aa->lock);
+       ret = __s5k6aa_set_frame_interval(s5k6aa, fi);
+       s5k6aa->apply_cfg = 1;
+
+       mutex_unlock(&s5k6aa->lock);
+       return ret;
+}
+
+/*
+ * V4L2 subdev pad level and video operations
+ */
+static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd,
+                             struct v4l2_subdev_fh *fh,
+                             struct v4l2_subdev_frame_interval_enum *fie)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       const struct s5k6aa_interval *fi;
+       int ret = 0;
+
+       if (fie->index > ARRAY_SIZE(s5k6aa_intervals))
+               return -EINVAL;
+
+       v4l_bound_align_image(&fie->width, S5K6AA_WIN_WIDTH_MIN,
+                             S5K6AA_WIN_WIDTH_MAX, 1,
+                             &fie->height, S5K6AA_WIN_HEIGHT_MIN,
+                             S5K6AA_WIN_HEIGHT_MAX, 1, 0);
+
+       mutex_lock(&s5k6aa->lock);
+       fi = &s5k6aa_intervals[fie->index];
+       if (fie->width > fi->size.width || fie->height > fi->size.height)
+               ret = -EINVAL;
+       else
+               fie->interval = fi->interval;
+       mutex_unlock(&s5k6aa->lock);
+
+       return ret;
+}
+
+static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_fh *fh,
+                                struct v4l2_subdev_mbus_code_enum *code)
+{
+       if (code->index >= ARRAY_SIZE(s5k6aa_formats))
+               return -EINVAL;
+
+       code->code = s5k6aa_formats[code->index].code;
+       return 0;
+}
+
+static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_fh *fh,
+                                 struct v4l2_subdev_frame_size_enum *fse)
+{
+       int i = ARRAY_SIZE(s5k6aa_formats);
+
+       if (fse->index > 0)
+               return -EINVAL;
+
+       while (--i)
+               if (fse->code == s5k6aa_formats[i].code)
+                       break;
+
+       fse->code = s5k6aa_formats[i].code;
+       fse->min_width  = S5K6AA_WIN_WIDTH_MIN;
+       fse->max_width  = S5K6AA_WIN_WIDTH_MAX;
+       fse->max_height = S5K6AA_WIN_HEIGHT_MIN;
+       fse->min_height = S5K6AA_WIN_HEIGHT_MAX;
+
+       return 0;
+}
+
+static struct v4l2_rect *
+__s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa, struct v4l2_subdev_fh *fh,
+                      enum v4l2_subdev_format_whence which)
+{
+       if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               return &s5k6aa->ccd_rect;
+       if (which == V4L2_SUBDEV_FORMAT_TRY)
+               return v4l2_subdev_get_try_crop(fh, 0);
+
+       return NULL;
+}
+
+static void s5k6aa_try_format(struct s5k6aa *s5k6aa,
+                             struct v4l2_mbus_framefmt *mf)
+{
+       unsigned int index;
+
+       v4l_bound_align_image(&mf->width, S5K6AA_WIN_WIDTH_MIN,
+                             S5K6AA_WIN_WIDTH_MAX, 1,
+                             &mf->height, S5K6AA_WIN_HEIGHT_MIN,
+                             S5K6AA_WIN_HEIGHT_MAX, 1, 0);
+
+       if (mf->colorspace != V4L2_COLORSPACE_JPEG &&
+           mf->colorspace != V4L2_COLORSPACE_REC709)
+               mf->colorspace = V4L2_COLORSPACE_JPEG;
+
+       index = s5k6aa_get_pixfmt_index(s5k6aa, mf);
+
+       mf->colorspace  = s5k6aa_formats[index].colorspace;
+       mf->code        = s5k6aa_formats[index].code;
+       mf->field       = V4L2_FIELD_NONE;
+}
+
+static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+                         struct v4l2_subdev_format *fmt)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       struct v4l2_mbus_framefmt *mf;
+
+       memset(fmt->reserved, 0, sizeof(fmt->reserved));
+
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               mf = v4l2_subdev_get_try_format(fh, 0);
+               fmt->format = *mf;
+               return 0;
+       }
+
+       mutex_lock(&s5k6aa->lock);
+       fmt->format = s5k6aa->preset->mbus_fmt;
+       mutex_unlock(&s5k6aa->lock);
+
+       return 0;
+}
+
+static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+                         struct v4l2_subdev_format *fmt)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       struct s5k6aa_preset *preset = s5k6aa->preset;
+       struct v4l2_mbus_framefmt *mf;
+       struct v4l2_rect *crop;
+       int ret = 0;
+
+       mutex_lock(&s5k6aa->lock);
+       s5k6aa_try_format(s5k6aa, &fmt->format);
+
+       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+               mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+               crop = v4l2_subdev_get_try_crop(fh, 0);
+       } else {
+               if (s5k6aa->streaming) {
+                       ret = -EBUSY;
+               } else {
+                       mf = &preset->mbus_fmt;
+                       crop = &s5k6aa->ccd_rect;
+                       s5k6aa->apply_cfg = 1;
+               }
+       }
+
+       if (ret == 0) {
+               struct v4l2_subdev_frame_interval fiv = {
+                       .interval = {0, 1}
+               };
+
+               *mf = fmt->format;
+               /*
+                * Make sure the crop window is valid, i.e. its size is
+                * greater than the output window, as the ISP supports
+                * only down-scaling.
+                */
+               crop->width = clamp_t(unsigned int, crop->width, mf->width,
+                                     S5K6AA_WIN_WIDTH_MAX);
+               crop->height = clamp_t(unsigned int, crop->height, mf->height,
+                                      S5K6AA_WIN_HEIGHT_MAX);
+               crop->left = clamp_t(unsigned int, crop->left, 0,
+                                    S5K6AA_WIN_WIDTH_MAX - crop->width);
+               crop->top  = clamp_t(unsigned int, crop->top, 0,
+                                    S5K6AA_WIN_HEIGHT_MAX - crop->height);
+
+               /* Reset to minimum possible frame interval */
+               ret = __s5k6aa_set_frame_interval(s5k6aa, &fiv);
+       }
+       mutex_unlock(&s5k6aa->lock);
+
+       return ret;
+}
+
+static int s5k6aa_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+                          struct v4l2_subdev_crop *crop)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       struct v4l2_rect *rect;
+
+       memset(crop->reserved, 0, sizeof(crop->reserved));
+       mutex_lock(&s5k6aa->lock);
+
+       rect = __s5k6aa_get_crop_rect(s5k6aa, fh, crop->which);
+       if (rect)
+               crop->rect = *rect;
+
+       mutex_unlock(&s5k6aa->lock);
+
+       v4l2_dbg(1, debug, sd, "Current crop rectangle: (%d,%d)/%dx%d\n",
+                rect->left, rect->top, rect->width, rect->height);
+
+       return 0;
+}
+
+static int s5k6aa_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+                          struct v4l2_subdev_crop *crop)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       struct v4l2_mbus_framefmt *mf;
+       unsigned int max_x, max_y;
+       struct v4l2_rect *crop_r;
+
+       mutex_lock(&s5k6aa->lock);
+       crop_r = __s5k6aa_get_crop_rect(s5k6aa, fh, crop->which);
+
+       if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+               mf = &s5k6aa->preset->mbus_fmt;
+               s5k6aa->apply_crop = 1;
+       } else {
+               mf = v4l2_subdev_get_try_format(fh, 0);
+       }
+       v4l_bound_align_image(&crop->rect.width, mf->width,
+                             S5K6AA_WIN_WIDTH_MAX, 1,
+                             &crop->rect.height, mf->height,
+                             S5K6AA_WIN_HEIGHT_MAX, 1, 0);
+
+       max_x = (S5K6AA_WIN_WIDTH_MAX - crop->rect.width) & ~1;
+       max_y = (S5K6AA_WIN_HEIGHT_MAX - crop->rect.height) & ~1;
+
+       crop->rect.left = clamp_t(unsigned int, crop->rect.left, 0, max_x);
+       crop->rect.top  = clamp_t(unsigned int, crop->rect.top, 0, max_y);
+
+       *crop_r = crop->rect;
+
+       mutex_unlock(&s5k6aa->lock);
+
+       v4l2_dbg(1, debug, sd, "Set crop rectangle: (%d,%d)/%dx%d\n",
+                crop_r->left, crop_r->top, crop_r->width, crop_r->height);
+
+       return 0;
+}
+
+static const struct v4l2_subdev_pad_ops s5k6aa_pad_ops = {
+       .enum_mbus_code         = s5k6aa_enum_mbus_code,
+       .enum_frame_size        = s5k6aa_enum_frame_size,
+       .enum_frame_interval    = s5k6aa_enum_frame_interval,
+       .get_fmt                = s5k6aa_get_fmt,
+       .set_fmt                = s5k6aa_set_fmt,
+       .get_crop               = s5k6aa_get_crop,
+       .set_crop               = s5k6aa_set_crop,
+};
+
+static const struct v4l2_subdev_video_ops s5k6aa_video_ops = {
+       .g_frame_interval       = s5k6aa_g_frame_interval,
+       .s_frame_interval       = s5k6aa_s_frame_interval,
+       .s_stream               = s5k6aa_s_stream,
+};
+
+/*
+ * V4L2 subdev controls
+ */
+
+static int s5k6aa_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       int idx, err = 0;
+
+       v4l2_dbg(1, debug, sd, "ctrl: 0x%x, value: %d\n", ctrl->id, ctrl->val);
+
+       mutex_lock(&s5k6aa->lock);
+       /*
+        * If the device is not powered up by the host driver do
+        * not apply any controls to H/W at this time. Instead
+        * the controls will be restored right after power-up.
+        */
+       if (s5k6aa->power == 0)
+               goto unlock;
+       idx = s5k6aa->preset->index;
+
+       switch (ctrl->id) {
+       case V4L2_CID_AUTO_WHITE_BALANCE:
+               err = s5k6aa_set_awb(s5k6aa, ctrl->val);
+               break;
+
+       case V4L2_CID_BRIGHTNESS:
+               err = s5k6aa_write(client, REG_USER_BRIGHTNESS, ctrl->val);
+               break;
+
+       case V4L2_CID_COLORFX:
+               err = s5k6aa_set_colorfx(s5k6aa, ctrl->val);
+               break;
+
+       case V4L2_CID_CONTRAST:
+               err = s5k6aa_write(client, REG_USER_CONTRAST, ctrl->val);
+               break;
+
+       case V4L2_CID_EXPOSURE_AUTO:
+               err = s5k6aa_set_auto_exposure(s5k6aa, ctrl->val);
+               break;
+
+       case V4L2_CID_HFLIP:
+               err = s5k6aa_set_mirror(s5k6aa, ctrl->val);
+               if (err)
+                       break;
+               err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
+               break;
+
+       case V4L2_CID_POWER_LINE_FREQUENCY:
+               err = s5k6aa_set_anti_flicker(s5k6aa, ctrl->val);
+               break;
+
+       case V4L2_CID_SATURATION:
+               err = s5k6aa_write(client, REG_USER_SATURATION, ctrl->val);
+               break;
+
+       case V4L2_CID_SHARPNESS:
+               err = s5k6aa_write(client, REG_USER_SHARPBLUR, ctrl->val);
+               break;
+
+       case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
+               err = s5k6aa_write(client, REG_P_COLORTEMP(idx), ctrl->val);
+               if (err)
+                       break;
+               err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
+               break;
+       }
+unlock:
+       mutex_unlock(&s5k6aa->lock);
+       return err;
+}
+
+static const struct v4l2_ctrl_ops s5k6aa_ctrl_ops = {
+       .s_ctrl = s5k6aa_s_ctrl,
+};
+
+static int s5k6aa_log_status(struct v4l2_subdev *sd)
+{
+       v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
+       return 0;
+}
+
+#define V4L2_CID_RED_GAIN      (V4L2_CTRL_CLASS_CAMERA | 0x1001)
+#define V4L2_CID_GREEN_GAIN    (V4L2_CTRL_CLASS_CAMERA | 0x1002)
+#define V4L2_CID_BLUE_GAIN     (V4L2_CTRL_CLASS_CAMERA | 0x1003)
+
+static const struct v4l2_ctrl_config s5k6aa_ctrls[] = {
+       {
+               .ops    = &s5k6aa_ctrl_ops,
+               .id     = V4L2_CID_RED_GAIN,
+               .type   = V4L2_CTRL_TYPE_INTEGER,
+               .name   = "Gain, Red",
+               .min    = 0,
+               .max    = 256,
+               .def    = 127,
+               .step   = 1,
+       }, {
+               .ops    = &s5k6aa_ctrl_ops,
+               .id     = V4L2_CID_GREEN_GAIN,
+               .type   = V4L2_CTRL_TYPE_INTEGER,
+               .name   = "Gain, Green",
+               .min    = 0,
+               .max    = 256,
+               .def    = 127,
+               .step   = 1,
+       }, {
+               .ops    = &s5k6aa_ctrl_ops,
+               .id     = V4L2_CID_BLUE_GAIN,
+               .type   = V4L2_CTRL_TYPE_INTEGER,
+               .name   = "Gain, Blue",
+               .min    = 0,
+               .max    = 256,
+               .def    = 127,
+               .step   = 1,
+       },
+};
+
+static int s5k6aa_initialize_ctrls(struct s5k6aa *s5k6aa)
+{
+       const struct v4l2_ctrl_ops *ops = &s5k6aa_ctrl_ops;
+       struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
+       struct v4l2_ctrl_handler *hdl = &ctrls->handler;
+
+       int ret = v4l2_ctrl_handler_init(hdl, 16);
+       if (ret)
+               return ret;
+       /* Auto white balance cluster */
+       ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
+                                      0, 1, 1, 1);
+       ctrls->gain_red = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[0], NULL);
+       ctrls->gain_green = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[1], NULL);
+       ctrls->gain_blue = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[2], NULL);
+       v4l2_ctrl_auto_cluster(4, &ctrls->awb, 0, false);
+
+       ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
+       ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
+       v4l2_ctrl_cluster(2, &ctrls->hflip);
+
+       ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
+                               V4L2_CID_EXPOSURE_AUTO,
+                               V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
+       /* Exposure time: x 1 us */
+       ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
+                                           0, 6000000U, 1, 100000U);
+       /* Total gain: 256 <=> 1x */
+       ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
+                                       0, 256, 1, 256);
+       v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
+
+       v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
+                              V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
+                              V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
+
+       v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
+                              V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
+
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+                         0, 256, 1, 0);
+
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
+       v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
+
+       if (hdl->error) {
+               ret = hdl->error;
+               v4l2_ctrl_handler_free(hdl);
+               return ret;
+       }
+
+       s5k6aa->sd.ctrl_handler = hdl;
+       return 0;
+}
+
+/*
+ * V4L2 subdev internal operations
+ */
+static int s5k6aa_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+       struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
+       struct v4l2_rect *crop = v4l2_subdev_get_try_crop(fh, 0);
+
+       format->colorspace = s5k6aa_formats[0].colorspace;
+       format->code = s5k6aa_formats[0].code;
+       format->width = S5K6AA_OUT_WIDTH_DEF;
+       format->height = S5K6AA_OUT_HEIGHT_DEF;
+       format->field = V4L2_FIELD_NONE;
+
+       crop->width = S5K6AA_WIN_WIDTH_MAX;
+       crop->height = S5K6AA_WIN_HEIGHT_MAX;
+       crop->left = 0;
+       crop->top = 0;
+
+       return 0;
+}
+
+int s5k6aa_check_fw_revision(struct s5k6aa *s5k6aa)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+       u16 api_ver = 0, fw_rev = 0;
+
+       int ret = s5k6aa_set_ahb_address(client);
+
+       if (!ret)
+               ret = s5k6aa_read(client, REG_FW_APIVER, &api_ver);
+       if (!ret)
+               ret = s5k6aa_read(client, REG_FW_REVISION, &fw_rev);
+       if (ret) {
+               v4l2_err(&s5k6aa->sd, "FW revision check failed!\n");
+               return ret;
+       }
+
+       v4l2_info(&s5k6aa->sd, "FW API ver.: 0x%X, FW rev.: 0x%X\n",
+                 api_ver, fw_rev);
+
+       return api_ver == S5K6AAFX_FW_APIVER ? 0 : -ENODEV;
+}
+
+static int s5k6aa_registered(struct v4l2_subdev *sd)
+{
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+       int ret;
+
+       mutex_lock(&s5k6aa->lock);
+       ret = __s5k6aa_power_on(s5k6aa);
+       if (!ret) {
+               msleep(100);
+               ret = s5k6aa_check_fw_revision(s5k6aa);
+               __s5k6aa_power_off(s5k6aa);
+       }
+       mutex_unlock(&s5k6aa->lock);
+
+       return ret;
+}
+
+static const struct v4l2_subdev_internal_ops s5k6aa_subdev_internal_ops = {
+       .registered = s5k6aa_registered,
+       .open = s5k6aa_open,
+};
+
+static const struct v4l2_subdev_core_ops s5k6aa_core_ops = {
+       .s_power = s5k6aa_set_power,
+       .log_status = s5k6aa_log_status,
+};
+
+static const struct v4l2_subdev_ops s5k6aa_subdev_ops = {
+       .core = &s5k6aa_core_ops,
+       .pad = &s5k6aa_pad_ops,
+       .video = &s5k6aa_video_ops,
+};
+
+/*
+ * GPIO setup
+ */
+static int s5k6aa_configure_gpio(int nr, int val, const char *name)
+{
+       unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+       int ret;
+
+       if (!gpio_is_valid(nr))
+               return 0;
+       ret = gpio_request_one(nr, flags, name);
+       if (!ret)
+               gpio_export(nr, 0);
+       return ret;
+}
+
+static void s5k6aa_free_gpios(struct s5k6aa *s5k6aa)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(s5k6aa->gpio); i++) {
+               if (!gpio_is_valid(s5k6aa->gpio[i].gpio))
+                       continue;
+               gpio_free(s5k6aa->gpio[i].gpio);
+               s5k6aa->gpio[i].gpio = -EINVAL;
+       }
+}
+
+static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
+                                 const struct s5k6aa_platform_data *pdata)
+{
+       const struct s5k6aa_gpio *gpio = &pdata->gpio_stby;
+       int ret;
+
+       s5k6aa->gpio[STBY].gpio = -EINVAL;
+       s5k6aa->gpio[RST].gpio  = -EINVAL;
+
+       ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_STBY");
+       if (ret) {
+               s5k6aa_free_gpios(s5k6aa);
+               return ret;
+       }
+       s5k6aa->gpio[STBY] = *gpio;
+       if (gpio_is_valid(gpio->gpio))
+               gpio_set_value(gpio->gpio, 0);
+
+       gpio = &pdata->gpio_reset;
+       ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_RST");
+       if (ret) {
+               s5k6aa_free_gpios(s5k6aa);
+               return ret;
+       }
+       s5k6aa->gpio[RST] = *gpio;
+       if (gpio_is_valid(gpio->gpio))
+               gpio_set_value(gpio->gpio, 0);
+
+       return 0;
+}
+
+static int s5k6aa_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       const struct s5k6aa_platform_data *pdata = client->dev.platform_data;
+       struct v4l2_subdev *sd;
+       struct s5k6aa *s5k6aa;
+       int i, ret;
+
+       if (pdata == NULL) {
+               dev_err(&client->dev, "Platform data not specified\n");
+               return -EINVAL;
+       }
+
+       if (pdata->mclk_frequency == 0) {
+               dev_err(&client->dev, "MCLK frequency not specified\n");
+               return -EINVAL;
+       }
+
+       s5k6aa = kzalloc(sizeof(*s5k6aa), GFP_KERNEL);
+       if (!s5k6aa)
+               return -ENOMEM;
+
+       mutex_init(&s5k6aa->lock);
+
+       s5k6aa->mclk_frequency = pdata->mclk_frequency;
+       s5k6aa->bus_type = pdata->bus_type;
+       s5k6aa->mipi_lanes = pdata->nlanes;
+       s5k6aa->s_power = pdata->set_power;
+       s5k6aa->inv_hflip = pdata->horiz_flip;
+       s5k6aa->inv_vflip = pdata->vert_flip;
+
+       sd = &s5k6aa->sd;
+       strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
+       v4l2_i2c_subdev_init(sd, client, &s5k6aa_subdev_ops);
+
+       sd->internal_ops = &s5k6aa_subdev_internal_ops;
+       sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+       s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
+       sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
+       ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0);
+       if (ret)
+               goto out_err1;
+
+       ret = s5k6aa_configure_gpios(s5k6aa, pdata);
+       if (ret)
+               goto out_err2;
+
+       for (i = 0; i < S5K6AA_NUM_SUPPLIES; i++)
+               s5k6aa->supplies[i].supply = s5k6aa_supply_names[i];
+
+       ret = regulator_bulk_get(&client->dev, S5K6AA_NUM_SUPPLIES,
+                                s5k6aa->supplies);
+       if (ret) {
+               dev_err(&client->dev, "Failed to get regulators\n");
+               goto out_err3;
+       }
+
+       ret = s5k6aa_initialize_ctrls(s5k6aa);
+       if (ret)
+               goto out_err4;
+
+       s5k6aa_presets_data_init(s5k6aa);
+
+       s5k6aa->ccd_rect.width = S5K6AA_WIN_WIDTH_MAX;
+       s5k6aa->ccd_rect.height = S5K6AA_WIN_HEIGHT_MAX;
+       s5k6aa->ccd_rect.left = 0;
+       s5k6aa->ccd_rect.top = 0;
+
+       return 0;
+
+out_err4:
+       regulator_bulk_free(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
+out_err3:
+       s5k6aa_free_gpios(s5k6aa);
+out_err2:
+       media_entity_cleanup(&s5k6aa->sd.entity);
+out_err1:
+       kfree(s5k6aa);
+       return ret;
+}
+
+static int s5k6aa_remove(struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct s5k6aa *s5k6aa = to_s5k6aa(sd);
+
+       v4l2_device_unregister_subdev(sd);
+       v4l2_ctrl_handler_free(sd->ctrl_handler);
+       media_entity_cleanup(&sd->entity);
+       regulator_bulk_free(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
+       s5k6aa_free_gpios(s5k6aa);
+       kfree(s5k6aa);
+
+       return 0;
+}
+
+static const struct i2c_device_id s5k6aa_id[] = {
+       { DRIVER_NAME, 0 },
+       { },
+};
+MODULE_DEVICE_TABLE(i2c, s5k6aa_id);
+
+
+static struct i2c_driver s5k6aa_i2c_driver = {
+       .driver = {
+               .name = DRIVER_NAME
+       },
+       .probe          = s5k6aa_probe,
+       .remove         = s5k6aa_remove,
+       .id_table       = s5k6aa_id,
+};
+
+static int __init s5k6aa_init(void)
+{
+       return i2c_add_driver(&s5k6aa_i2c_driver);
+}
+
+static void __exit s5k6aa_exit(void)
+{
+       i2c_del_driver(&s5k6aa_i2c_driver);
+}
+
+module_init(s5k6aa_init);
+module_exit(s5k6aa_exit);
+
+MODULE_DESCRIPTION("Samsung S5K6AA(FX) SXGA camera driver");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+MODULE_LICENSE("GPL");
index 931f469..c8d91b0 100644 (file)
@@ -246,9 +246,9 @@ static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane)
        return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
 }
 
-static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
-                      unsigned int *num_planes, unsigned int sizes[],
-                      void *allocators[])
+static int queue_setup(struct vb2_queue *vq,  const struct v4l2_format *pfmt,
+                      unsigned int *num_buffers, unsigned int *num_planes,
+                      unsigned int sizes[], void *allocators[])
 {
        struct fimc_ctx *ctx = vq->drv_priv;
        struct fimc_fmt *fmt = ctx->d_frame.fmt;
index 6c1c9cb..19ca6db 100644 (file)
@@ -670,9 +670,9 @@ static void fimc_job_abort(void *priv)
        fimc_m2m_shutdown(priv);
 }
 
-static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
-                           unsigned int *num_planes, unsigned int sizes[],
-                           void *allocators[])
+static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+                           unsigned int *num_buffers, unsigned int *num_planes,
+                           unsigned int sizes[], void *allocators[])
 {
        struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
        struct fimc_frame *f;
index 5f4da80..f2481a8 100644 (file)
@@ -38,7 +38,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
         * into kernel. */
        mfc_debug_enter();
        err = request_firmware((const struct firmware **)&fw_blob,
-                                    "s5pc110-mfc.fw", dev->v4l2_dev.dev);
+                                    "s5p-mfc.fw", dev->v4l2_dev.dev);
        if (err != 0) {
                mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
                return -EINVAL;
@@ -116,7 +116,7 @@ int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
         * into kernel. */
        mfc_debug_enter();
        err = request_firmware((const struct firmware **)&fw_blob,
-                                    "s5pc110-mfc.fw", dev->v4l2_dev.dev);
+                                    "s5p-mfc.fw", dev->v4l2_dev.dev);
        if (err != 0) {
                mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
                return -EINVAL;
index bfbe084..725634d 100644 (file)
@@ -744,9 +744,10 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
        .vidioc_g_crop = vidioc_g_crop,
 };
 
-static int s5p_mfc_queue_setup(struct vb2_queue *vq, unsigned int *buf_count,
-                              unsigned int *plane_count, unsigned int psize[],
-                              void *allocators[])
+static int s5p_mfc_queue_setup(struct vb2_queue *vq,
+                       const struct v4l2_format *fmt, unsigned int *buf_count,
+                       unsigned int *plane_count, unsigned int psize[],
+                       void *allocators[])
 {
        struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
 
index 4c90e53..ecef127 100644 (file)
@@ -1513,8 +1513,9 @@ static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
 }
 
 static int s5p_mfc_queue_setup(struct vb2_queue *vq,
-                      unsigned int *buf_count, unsigned int *plane_count,
-                      unsigned int psize[], void *allocators[])
+                       const struct v4l2_format *fmt,
+                       unsigned int *buf_count, unsigned int *plane_count,
+                       unsigned int psize[], void *allocators[])
 {
        struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
 
index 4917e2c..e16d3a4 100644 (file)
@@ -727,8 +727,8 @@ static const struct v4l2_file_operations mxr_fops = {
        .unlocked_ioctl = video_ioctl2,
 };
 
-static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-       unsigned int *nplanes, unsigned int sizes[],
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
+       unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[],
        void *alloc_ctxs[])
 {
        struct mxr_layer *layer = vb2_get_drv_priv(vq);
index bc8d6bb..9b55068 100644 (file)
@@ -843,10 +843,10 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
 int saa7134_ir_start(struct saa7134_dev *dev);
 void saa7134_ir_stop(struct saa7134_dev *dev);
 #else
-#define saa7134_input_init1(dev)       (0)
-#define saa7134_input_fini(dev)                (0)
-#define saa7134_input_irq(dev)         (0)
-#define saa7134_probe_i2c_ir(dev)      (0)
-#define saa7134_ir_start(dev)          (0)
-#define saa7134_ir_stop(dev)           (0)
+#define saa7134_input_init1(dev)       ((void)0)
+#define saa7134_input_fini(dev)                ((void)0)
+#define saa7134_input_irq(dev)         ((void)0)
+#define saa7134_probe_i2c_ir(dev)      ((void)0)
+#define saa7134_ir_start(dev)          ((void)0)
+#define saa7134_ir_stop(dev)           ((void)0)
 #endif
index 8615fb8..f390682 100644 (file)
@@ -90,7 +90,6 @@
 struct sh_mobile_ceu_buffer {
        struct vb2_buffer vb; /* v4l buffer must be first */
        struct list_head queue;
-       enum v4l2_mbus_pixelcode code;
 };
 
 struct sh_mobile_ceu_dev {
@@ -100,7 +99,8 @@ struct sh_mobile_ceu_dev {
 
        unsigned int irq;
        void __iomem *base;
-       unsigned long video_limit;
+       size_t video_limit;
+       size_t buf_total;
 
        spinlock_t lock;                /* Protects video buffer lists */
        struct list_head capture;
@@ -121,7 +121,7 @@ struct sh_mobile_ceu_dev {
 };
 
 struct sh_mobile_ceu_cam {
-       /* CEU offsets within scaled by the CEU camera output */
+       /* CEU offsets within the camera output, before the CEU scaler */
        unsigned int ceu_left;
        unsigned int ceu_top;
        /* Client output, as seen by the CEU */
@@ -144,30 +144,6 @@ static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb)
        return container_of(vb, struct sh_mobile_ceu_buffer, vb);
 }
 
-static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
-{
-       unsigned long flags;
-
-       flags = SOCAM_MASTER |
-               SOCAM_PCLK_SAMPLE_RISING |
-               SOCAM_HSYNC_ACTIVE_HIGH |
-               SOCAM_HSYNC_ACTIVE_LOW |
-               SOCAM_VSYNC_ACTIVE_HIGH |
-               SOCAM_VSYNC_ACTIVE_LOW |
-               SOCAM_DATA_ACTIVE_HIGH;
-
-       if (pcdev->pdata->flags & SH_CEU_FLAG_USE_8BIT_BUS)
-               flags |= SOCAM_DATAWIDTH_8;
-
-       if (pcdev->pdata->flags & SH_CEU_FLAG_USE_16BIT_BUS)
-               flags |= SOCAM_DATAWIDTH_16;
-
-       if (flags & SOCAM_DATAWIDTH_MASK)
-               return flags;
-
-       return 0;
-}
-
 static void ceu_write(struct sh_mobile_ceu_dev *priv,
                      unsigned long reg_offs, u32 data)
 {
@@ -216,33 +192,61 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
 /*
  *  Videobuf operations
  */
+
+/*
+ * .queue_setup() is called to check, whether the driver can accept the
+ *               requested number of buffers and to fill in plane sizes
+ *               for the current frame format if required
+ */
 static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
+                       const struct v4l2_format *fmt,
                        unsigned int *count, unsigned int *num_planes,
                        unsigned int sizes[], void *alloc_ctxs[])
 {
        struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
-       int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
-                                               icd->current_fmt->host_fmt);
+       int bytes_per_line;
+       unsigned int height;
 
+       if (fmt) {
+               const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
+                                                               fmt->fmt.pix.pixelformat);
+               if (!xlate)
+                       return -EINVAL;
+               bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
+                                                        xlate->host_fmt);
+               height = fmt->fmt.pix.height;
+       } else {
+               /* Called from VIDIOC_REQBUFS or in compatibility mode */
+               bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+                                               icd->current_fmt->host_fmt);
+               height = icd->user_height;
+       }
        if (bytes_per_line < 0)
                return bytes_per_line;
 
-       *num_planes = 1;
+       sizes[0] = bytes_per_line * height;
 
-       pcdev->sequence = 0;
-       sizes[0] = bytes_per_line * icd->user_height;
        alloc_ctxs[0] = pcdev->alloc_ctx;
 
+       if (!vq->num_buffers)
+               pcdev->sequence = 0;
+
        if (!*count)
                *count = 2;
 
-       if (pcdev->video_limit) {
-               if (PAGE_ALIGN(sizes[0]) * *count > pcdev->video_limit)
-                       *count = pcdev->video_limit / PAGE_ALIGN(sizes[0]);
+       /* If *num_planes != 0, we have already verified *count. */
+       if (pcdev->video_limit && !*num_planes) {
+               size_t size = PAGE_ALIGN(sizes[0]) * *count;
+
+               if (size + pcdev->buf_total > pcdev->video_limit)
+                       *count = (pcdev->video_limit - pcdev->buf_total) /
+                               PAGE_ALIGN(sizes[0]);
        }
 
+       *num_planes = 1;
+
        dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
 
        return 0;
@@ -267,6 +271,7 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
        unsigned long top1, top2;
        unsigned long bottom1, bottom2;
        u32 status;
+       bool planar;
        int ret = 0;
 
        /*
@@ -314,17 +319,29 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 
        phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0);
 
-       ceu_write(pcdev, top1, phys_addr_top);
-       if (V4L2_FIELD_NONE != pcdev->field) {
-               phys_addr_bottom = phys_addr_top + icd->user_width;
-               ceu_write(pcdev, bottom1, phys_addr_bottom);
-       }
-
        switch (icd->current_fmt->host_fmt->fourcc) {
        case V4L2_PIX_FMT_NV12:
        case V4L2_PIX_FMT_NV21:
        case V4L2_PIX_FMT_NV16:
        case V4L2_PIX_FMT_NV61:
+               planar = true;
+               break;
+       default:
+               planar = false;
+       }
+
+       ceu_write(pcdev, top1, phys_addr_top);
+       if (V4L2_FIELD_NONE != pcdev->field) {
+               if (planar)
+                       phys_addr_bottom = phys_addr_top + icd->user_width;
+               else
+                       phys_addr_bottom = phys_addr_top +
+                               soc_mbus_bytes_per_line(icd->user_width,
+                                                       icd->current_fmt->host_fmt);
+               ceu_write(pcdev, bottom1, phys_addr_bottom);
+       }
+
+       if (planar) {
                phys_addr_top += icd->user_width *
                        icd->user_height;
                ceu_write(pcdev, top2, phys_addr_top);
@@ -340,24 +357,41 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 }
 
 static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
+{
+       struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
+
+       /* Added list head initialization on alloc */
+       WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
+
+       return 0;
+}
+
+static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
 {
        struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
-       struct sh_mobile_ceu_buffer *buf;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+       struct sh_mobile_ceu_dev *pcdev = ici->priv;
+       struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
+       unsigned long size;
        int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
                                                icd->current_fmt->host_fmt);
-       unsigned long size;
 
        if (bytes_per_line < 0)
-               return bytes_per_line;
+               goto error;
 
-       buf = to_ceu_vb(vb);
+       size = icd->user_height * bytes_per_line;
+
+       if (vb2_plane_size(vb, 0) < size) {
+               dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
+                       vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
+               goto error;
+       }
+
+       vb2_set_plane_payload(vb, 0, size);
 
        dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
                vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
 
-       /* Added list head initialization on alloc */
-       WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
-
 #ifdef DEBUG
        /*
         * This can be useful if you want to see if we actually fill
@@ -367,31 +401,6 @@ static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
                memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
 #endif
 
-       BUG_ON(NULL == icd->current_fmt);
-
-       size = icd->user_height * bytes_per_line;
-
-       if (vb2_plane_size(vb, 0) < size) {
-               dev_err(icd->parent, "Buffer too small (%lu < %lu)\n",
-                       vb2_plane_size(vb, 0), size);
-               return -ENOBUFS;
-       }
-
-       vb2_set_plane_payload(vb, 0, size);
-
-       return 0;
-}
-
-static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
-{
-       struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
-       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-       struct sh_mobile_ceu_dev *pcdev = ici->priv;
-       struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
-
-       dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
-               vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
-
        spin_lock_irq(&pcdev->lock);
        list_add_tail(&buf->queue, &pcdev->capture);
 
@@ -405,6 +414,11 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
                sh_mobile_ceu_capture(pcdev);
        }
        spin_unlock_irq(&pcdev->lock);
+
+       return;
+
+error:
+       vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
 }
 
 static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
@@ -429,11 +443,23 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
        if (buf->queue.next)
                list_del_init(&buf->queue);
 
+       pcdev->buf_total -= PAGE_ALIGN(vb2_plane_size(vb, 0));
+       dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
+               pcdev->buf_total);
+
        spin_unlock_irq(&pcdev->lock);
 }
 
 static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
 {
+       struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+       struct sh_mobile_ceu_dev *pcdev = ici->priv;
+
+       pcdev->buf_total += PAGE_ALIGN(vb2_plane_size(vb, 0));
+       dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
+               pcdev->buf_total);
+
        /* This is for locking debugging only */
        INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
        return 0;
@@ -535,19 +561,29 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
 
        pm_runtime_get_sync(ici->v4l2_dev.dev);
 
+       pcdev->buf_total = 0;
+
        ret = sh_mobile_ceu_soft_reset(pcdev);
 
        csi2_sd = find_csi2(pcdev);
+       if (csi2_sd)
+               csi2_sd->grp_id = (long)icd;
 
        ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
-       if (ret != -ENODEV && ret != -ENOIOCTLCMD && ret < 0) {
+       if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
                pm_runtime_put_sync(ici->v4l2_dev.dev);
-       } else {
-               pcdev->icd = icd;
-               ret = 0;
+               return ret;
        }
 
-       return ret;
+       /*
+        * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
+        * has not found this soc-camera device among its clients
+        */
+       if (ret == -ENODEV && csi2_sd)
+               csi2_sd->grp_id = 0;
+       pcdev->icd = icd;
+
+       return 0;
 }
 
 /* Called with .video_lock held */
@@ -560,6 +596,8 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
        BUG_ON(icd != pcdev->icd);
 
        v4l2_subdev_call(csi2_sd, core, s_power, 0);
+       if (csi2_sd)
+               csi2_sd->grp_id = 0;
        /* disable capture, disable interrupts */
        ceu_write(pcdev, CEIER, 0);
        sh_mobile_ceu_soft_reset(pcdev);
@@ -628,22 +666,22 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
        left_offset     = cam->ceu_left;
        top_offset      = cam->ceu_top;
 
-       /* CEU cropping (CFSZR) is applied _after_ the scaling filter (CFLCR) */
+       WARN_ON(icd->user_width & 3 || icd->user_height & 3);
+
+       width = icd->user_width;
+
        if (pcdev->image_mode) {
                in_width = cam->width;
                if (!pcdev->is_16bit) {
                        in_width *= 2;
                        left_offset *= 2;
                }
-               width = icd->user_width;
-               cdwdr_width = icd->user_width;
+               cdwdr_width = width;
        } else {
-               int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
+               int bytes_per_line = soc_mbus_bytes_per_line(width,
                                                icd->current_fmt->host_fmt);
                unsigned int w_factor;
 
-               width = icd->user_width;
-
                switch (icd->current_fmt->host_fmt->packing) {
                case SOC_MBUS_PACKING_2X8_PADHI:
                        w_factor = 2;
@@ -653,10 +691,10 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
                }
 
                in_width = cam->width * w_factor;
-               left_offset = left_offset * w_factor;
+               left_offset *= w_factor;
 
                if (bytes_per_line < 0)
-                       cdwdr_width = icd->user_width;
+                       cdwdr_width = width;
                else
                        cdwdr_width = bytes_per_line;
        }
@@ -664,7 +702,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
        height = icd->user_height;
        in_height = cam->height;
        if (V4L2_FIELD_NONE != pcdev->field) {
-               height /= 2;
+               height = (height / 2) & ~3;
                in_height /= 2;
                top_offset /= 2;
                cdwdr_width *= 2;
@@ -686,6 +724,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
 
        ceu_write(pcdev, CAMOR, camor);
        ceu_write(pcdev, CAPWR, (in_height << 16) | in_width);
+       /* CFSZR clipping is applied _after_ the scaling filter (CFLCR) */
        ceu_write(pcdev, CFSZR, (height << 16) | width);
        ceu_write(pcdev, CDWDR, cdwdr_width);
 }
@@ -723,66 +762,93 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
                ceu_write(pcdev, CAPSR, capsr);
 }
 
+/* Find the bus subdevice driver, e.g., CSI2 */
+static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev,
+                                          struct soc_camera_device *icd)
+{
+       if (pcdev->csi2_pdev) {
+               struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
+               if (csi2_sd && csi2_sd->grp_id == (u32)icd)
+                       return csi2_sd;
+       }
+
+       return soc_camera_to_subdev(icd);
+}
+
+#define CEU_BUS_FLAGS (V4L2_MBUS_MASTER |      \
+               V4L2_MBUS_PCLK_SAMPLE_RISING |  \
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH |   \
+               V4L2_MBUS_HSYNC_ACTIVE_LOW |    \
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH |   \
+               V4L2_MBUS_VSYNC_ACTIVE_LOW |    \
+               V4L2_MBUS_DATA_ACTIVE_HIGH)
+
 /* Capture is not running, no interrupts, no locking needed */
 static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
                                       __u32 pixfmt)
 {
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
-       int ret;
-       unsigned long camera_flags, common_flags, value;
-       int yuv_lineskip;
+       struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
        struct sh_mobile_ceu_cam *cam = icd->host_priv;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       unsigned long value, common_flags = CEU_BUS_FLAGS;
        u32 capsr = capture_save_reset(pcdev);
+       unsigned int yuv_lineskip;
+       int ret;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-       common_flags = soc_camera_bus_param_compatible(camera_flags,
-                                                      make_bus_param(pcdev));
-       if (!common_flags)
-               return -EINVAL;
+       /*
+        * If the client doesn't implement g_mbus_config, we just use our
+        * platform data
+        */
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret) {
+               common_flags = soc_mbus_config_compatible(&cfg,
+                                                         common_flags);
+               if (!common_flags)
+                       return -EINVAL;
+       } else if (ret != -ENOIOCTLCMD) {
+               return ret;
+       }
 
        /* Make choises, based on platform preferences */
-       if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
                if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
                else
-                       common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
        }
 
-       if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
-           (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+       if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
+           (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
                if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
-                       common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+                       common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
                else
-                       common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+                       common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
        }
 
-       ret = icd->ops->set_bus_param(icd, common_flags);
-       if (ret < 0)
+       cfg.flags = common_flags;
+       ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
+       if (ret < 0 && ret != -ENOIOCTLCMD)
                return ret;
 
-       switch (common_flags & SOCAM_DATAWIDTH_MASK) {
-       case SOCAM_DATAWIDTH_8:
-               pcdev->is_16bit = 0;
-               break;
-       case SOCAM_DATAWIDTH_16:
+       if (icd->current_fmt->host_fmt->bits_per_sample > 8)
                pcdev->is_16bit = 1;
-               break;
-       default:
-               return -EINVAL;
-       }
+       else
+               pcdev->is_16bit = 0;
 
        ceu_write(pcdev, CRCNTR, 0);
        ceu_write(pcdev, CRCMPR, 0);
 
        value = 0x00000010; /* data fetch by default */
-       yuv_lineskip = 0;
+       yuv_lineskip = 0x10;
 
        switch (icd->current_fmt->host_fmt->fourcc) {
        case V4L2_PIX_FMT_NV12:
        case V4L2_PIX_FMT_NV21:
-               yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */
+               /* convert 4:2:2 -> 4:2:0 */
+               yuv_lineskip = 0; /* skip for NV12/21, no skip for NV16/61 */
                /* fall-through */
        case V4L2_PIX_FMT_NV16:
        case V4L2_PIX_FMT_NV61:
@@ -808,8 +874,8 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
            icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61)
                value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
 
-       value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
-       value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
+       value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
+       value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
        value |= pcdev->is_16bit ? 1 << 12 : 0;
 
        /* CSI2 mode */
@@ -852,9 +918,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
         * using 7 we swap the data bytes to match the incoming order:
         * D0, D1, D2, D3, D4, D5, D6, D7
         */
-       value = 0x00000017;
-       if (yuv_lineskip)
-               value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */
+       value = 0x00000007 | yuv_lineskip;
 
        ceu_write(pcdev, CDOCR, value);
        ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
@@ -875,13 +939,19 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
 {
        struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
-       unsigned long camera_flags, common_flags;
+       struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
+       unsigned long common_flags = CEU_BUS_FLAGS;
+       struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+       int ret;
 
-       camera_flags = icd->ops->query_bus_param(icd);
-       common_flags = soc_camera_bus_param_compatible(camera_flags,
-                                                      make_bus_param(pcdev));
-       if (!common_flags || buswidth > 16 ||
-           (buswidth > 8 && !(common_flags & SOCAM_DATAWIDTH_16)))
+       ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
+       if (!ret)
+               common_flags = soc_mbus_config_compatible(&cfg,
+                                                         common_flags);
+       else if (ret != -ENOIOCTLCMD)
+               return ret;
+
+       if (!common_flags || buswidth > 16)
                return -EINVAL;
 
        return 0;
@@ -891,26 +961,26 @@ static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
        {
                .fourcc                 = V4L2_PIX_FMT_NV12,
                .name                   = "NV12",
-               .bits_per_sample        = 12,
-               .packing                = SOC_MBUS_PACKING_NONE,
+               .bits_per_sample        = 8,
+               .packing                = SOC_MBUS_PACKING_1_5X8,
                .order                  = SOC_MBUS_ORDER_LE,
        }, {
                .fourcc                 = V4L2_PIX_FMT_NV21,
                .name                   = "NV21",
-               .bits_per_sample        = 12,
-               .packing                = SOC_MBUS_PACKING_NONE,
+               .bits_per_sample        = 8,
+               .packing                = SOC_MBUS_PACKING_1_5X8,
                .order                  = SOC_MBUS_ORDER_LE,
        }, {
                .fourcc                 = V4L2_PIX_FMT_NV16,
                .name                   = "NV16",
-               .bits_per_sample        = 16,
-               .packing                = SOC_MBUS_PACKING_NONE,
+               .bits_per_sample        = 8,
+               .packing                = SOC_MBUS_PACKING_2X8_PADHI,
                .order                  = SOC_MBUS_ORDER_LE,
        }, {
                .fourcc                 = V4L2_PIX_FMT_NV61,
                .name                   = "NV61",
-               .bits_per_sample        = 16,
-               .packing                = SOC_MBUS_PACKING_NONE,
+               .bits_per_sample        = 8,
+               .packing                = SOC_MBUS_PACKING_2X8_PADHI,
                .order                  = SOC_MBUS_ORDER_LE,
        },
 };
@@ -919,6 +989,8 @@ static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
 static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
 {
        return  fmt->packing == SOC_MBUS_PACKING_NONE ||
+               (fmt->bits_per_sample == 8 &&
+                fmt->packing == SOC_MBUS_PACKING_1_5X8) ||
                (fmt->bits_per_sample == 8 &&
                 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
                (fmt->bits_per_sample > 8 &&
@@ -927,6 +999,38 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
 
 static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
 
+static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl)
+{
+       return container_of(ctrl->handler, struct soc_camera_device,
+                                                       ctrl_handler);
+}
+
+static int sh_mobile_ceu_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct soc_camera_device *icd = ctrl_to_icd(ctrl);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+       struct sh_mobile_ceu_dev *pcdev = ici->priv;
+
+       switch (ctrl->id) {
+       case V4L2_CID_SHARPNESS:
+               switch (icd->current_fmt->host_fmt->fourcc) {
+               case V4L2_PIX_FMT_NV12:
+               case V4L2_PIX_FMT_NV21:
+               case V4L2_PIX_FMT_NV16:
+               case V4L2_PIX_FMT_NV61:
+                       ceu_write(pcdev, CLFCR, !ctrl->val);
+                       return 0;
+               }
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static const struct v4l2_ctrl_ops sh_mobile_ceu_ctrl_ops = {
+       .s_ctrl = sh_mobile_ceu_s_ctrl,
+};
+
 static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx,
                                     struct soc_camera_format_xlate *xlate)
 {
@@ -952,6 +1056,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
        }
 
        if (!pcdev->pdata->csi2) {
+               /* Are there any restrictions in the CSI-2 case? */
                ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
                if (ret < 0)
                        return 0;
@@ -962,6 +1067,12 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
                struct v4l2_rect rect;
                int shift = 0;
 
+               /* Add our control */
+               v4l2_ctrl_new_std(&icd->ctrl_handler, &sh_mobile_ceu_ctrl_ops,
+                                 V4L2_CID_SHARPNESS, 0, 1, 1, 0);
+               if (icd->ctrl_handler.error)
+                       return icd->ctrl_handler.error;
+
                /* FIXME: subwindow is lost between close / open */
 
                /* Cache current client geometry */
@@ -1004,9 +1115,6 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
                cam->width      = mf.width;
                cam->height     = mf.height;
 
-               cam->width      = mf.width;
-               cam->height     = mf.height;
-
                icd->host_priv = cam;
        } else {
                cam = icd->host_priv;
@@ -1278,6 +1386,7 @@ static int client_s_fmt(struct soc_camera_device *icd,
        unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
        unsigned int max_width, max_height;
        struct v4l2_cropcap cap;
+       bool ceu_1to1;
        int ret;
 
        ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video,
@@ -1287,7 +1396,14 @@ static int client_s_fmt(struct soc_camera_device *icd,
 
        dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
 
-       if ((width == mf->width && height == mf->height) || !ceu_can_scale)
+       if (width == mf->width && height == mf->height) {
+               /* Perfect! The client has done it all. */
+               ceu_1to1 = true;
+               goto update_cache;
+       }
+
+       ceu_1to1 = false;
+       if (!ceu_can_scale)
                goto update_cache;
 
        cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1327,7 +1443,10 @@ update_cache:
        if (ret < 0)
                return ret;
 
-       update_subrect(cam);
+       if (ceu_1to1)
+               cam->subrect = cam->rect;
+       else
+               update_subrect(cam);
 
        return 0;
 }
@@ -1414,7 +1533,10 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
        capsr = capture_save_reset(pcdev);
        dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
 
-       /* 1. - 2. Apply iterative camera S_CROP for new input window. */
+       /*
+        * 1. - 2. Apply iterative camera S_CROP for new input window, read back
+        * actual camera rectangle.
+        */
        ret = client_s_crop(icd, a, &cam_crop);
        if (ret < 0)
                return ret;
@@ -1498,8 +1620,9 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
                ceu_write(pcdev, CFLCR, cflcr);
        }
 
-       icd->user_width  = out_width;
-       icd->user_height = out_height;
+       icd->user_width  = out_width & ~3;
+       icd->user_height = out_height & ~3;
+       /* Offsets are applied at the CEU scaling filter input */
        cam->ceu_left    = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1;
        cam->ceu_top     = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1;
 
@@ -1538,7 +1661,7 @@ static int sh_mobile_ceu_get_crop(struct soc_camera_device *icd,
  * CEU crop, mapped backed onto the client input (subrect).
  */
 static void calculate_client_output(struct soc_camera_device *icd,
-               struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
+               const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
 {
        struct sh_mobile_ceu_cam *cam = icd->host_priv;
        struct device *dev = icd->parent;
@@ -1574,8 +1697,8 @@ static void calculate_client_output(struct soc_camera_device *icd,
        dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
 
        /*
-        * 4. Calculate client output window by applying combined scales to real
-        *    input window.
+        * 4. Calculate desired client output window by applying combined scales
+        *    to client (real) input window.
         */
        mf->width       = scale_down(cam->rect.width, scale_h);
        mf->height      = scale_down(cam->rect.height, scale_v);
@@ -1600,8 +1723,6 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
        bool image_mode;
        enum v4l2_field field;
 
-       dev_geo(dev, "S_FMT(pix=0x%x, %ux%u)\n", pixfmt, pix->width, pix->height);
-
        switch (pix->field) {
        default:
                pix->field = V4L2_FIELD_NONE;
@@ -1622,8 +1743,8 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
                return -EINVAL;
        }
 
-       /* 1.-4. Calculate client output geometry */
-       calculate_client_output(icd, &f->fmt.pix, &mf);
+       /* 1.-4. Calculate desired client output geometry */
+       calculate_client_output(icd, pix, &mf);
        mf.field        = pix->field;
        mf.colorspace   = pix->colorspace;
        mf.code         = xlate->code;
@@ -1639,6 +1760,9 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
                image_mode = false;
        }
 
+       dev_geo(dev, "S_FMT(pix=0x%x, fld 0x%x, code 0x%x, %ux%u)\n", pixfmt, mf.field, mf.code,
+               pix->width, pix->height);
+
        dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
 
        /* 5. - 9. */
@@ -1700,6 +1824,10 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
        pcdev->field = field;
        pcdev->image_mode = image_mode;
 
+       /* CFSZR requirement */
+       pix->width      &= ~3;
+       pix->height     &= ~3;
+
        return 0;
 }
 
@@ -1725,7 +1853,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
 
        /* FIXME: calculate using depth and bus width */
 
-       v4l_bound_align_image(&pix->width, 2, 2560, 1,
+       /* CFSZR requires height and width to be 4-pixel aligned */
+       v4l_bound_align_image(&pix->width, 2, 2560, 2,
                              &pix->height, 4, 1920, 2, 0);
 
        width = pix->width;
@@ -1778,6 +1907,9 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
                        pix->height = height;
        }
 
+       pix->width      &= ~3;
+       pix->height     &= ~3;
+
        dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n",
                __func__, ret, pix->pixelformat, pix->width, pix->height);
 
@@ -1824,8 +1956,8 @@ static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
                             out_height != f.fmt.pix.height))
                        ret = -EINVAL;
                if (!ret) {
-                       icd->user_width         = out_width;
-                       icd->user_height        = out_height;
+                       icd->user_width         = out_width & ~3;
+                       icd->user_height        = out_height & ~3;
                        ret = sh_mobile_ceu_set_bus_param(icd,
                                        icd->current_fmt->host_fmt->fourcc);
                }
@@ -1869,55 +2001,6 @@ static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
        return vb2_queue_init(q);
 }
 
-static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
-                                 struct v4l2_control *ctrl)
-{
-       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-       struct sh_mobile_ceu_dev *pcdev = ici->priv;
-       u32 val;
-
-       switch (ctrl->id) {
-       case V4L2_CID_SHARPNESS:
-               val = ceu_read(pcdev, CLFCR);
-               ctrl->value = val ^ 1;
-               return 0;
-       }
-       return -ENOIOCTLCMD;
-}
-
-static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd,
-                                 struct v4l2_control *ctrl)
-{
-       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-       struct sh_mobile_ceu_dev *pcdev = ici->priv;
-
-       switch (ctrl->id) {
-       case V4L2_CID_SHARPNESS:
-               switch (icd->current_fmt->host_fmt->fourcc) {
-               case V4L2_PIX_FMT_NV12:
-               case V4L2_PIX_FMT_NV21:
-               case V4L2_PIX_FMT_NV16:
-               case V4L2_PIX_FMT_NV61:
-                       ceu_write(pcdev, CLFCR, !ctrl->value);
-                       return 0;
-               }
-               return -EINVAL;
-       }
-       return -ENOIOCTLCMD;
-}
-
-static const struct v4l2_queryctrl sh_mobile_ceu_controls[] = {
-       {
-               .id             = V4L2_CID_SHARPNESS,
-               .type           = V4L2_CTRL_TYPE_BOOLEAN,
-               .name           = "Low-pass filter",
-               .minimum        = 0,
-               .maximum        = 1,
-               .step           = 1,
-               .default_value  = 0,
-       },
-};
-
 static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
        .owner          = THIS_MODULE,
        .add            = sh_mobile_ceu_add_device,
@@ -1929,14 +2012,10 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
        .set_livecrop   = sh_mobile_ceu_set_livecrop,
        .set_fmt        = sh_mobile_ceu_set_fmt,
        .try_fmt        = sh_mobile_ceu_try_fmt,
-       .set_ctrl       = sh_mobile_ceu_set_ctrl,
-       .get_ctrl       = sh_mobile_ceu_get_ctrl,
        .poll           = sh_mobile_ceu_poll,
        .querycap       = sh_mobile_ceu_querycap,
        .set_bus_param  = sh_mobile_ceu_set_bus_param,
        .init_videobuf2 = sh_mobile_ceu_init_videobuf,
-       .controls       = sh_mobile_ceu_controls,
-       .num_controls   = ARRAY_SIZE(sh_mobile_ceu_controls),
 };
 
 struct bus_wait {
index 2893a01..37706eb 100644 (file)
@@ -19,6 +19,7 @@
 #include <media/sh_mobile_ceu.h>
 #include <media/sh_mobile_csi2.h>
 #include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-device.h>
@@ -35,11 +36,10 @@ struct sh_csi2 {
        struct v4l2_subdev              subdev;
        struct list_head                list;
        unsigned int                    irq;
+       unsigned long                   mipi_flags;
        void __iomem                    *base;
        struct platform_device          *pdev;
        struct sh_csi2_client_config    *client;
-       unsigned long (*query_bus_param)(struct soc_camera_device *);
-       int (*set_bus_param)(struct soc_camera_device *, unsigned long);
 };
 
 static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
@@ -127,9 +127,34 @@ static int sh_csi2_s_fmt(struct v4l2_subdev *sd,
        return 0;
 }
 
+static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd,
+                                struct v4l2_mbus_config *cfg)
+{
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+               V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+
+       return 0;
+}
+
+static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd,
+                                const struct v4l2_mbus_config *cfg)
+{
+       struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
+       struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id;
+       struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
+       struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,
+                                             .flags = priv->mipi_flags};
+
+       return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg);
+}
+
 static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = {
        .s_mbus_fmt     = sh_csi2_s_fmt,
        .try_mbus_fmt   = sh_csi2_try_fmt,
+       .g_mbus_config  = sh_csi2_g_mbus_config,
+       .s_mbus_config  = sh_csi2_s_mbus_config,
 };
 
 static void sh_csi2_hwinit(struct sh_csi2 *priv)
@@ -144,11 +169,21 @@ static void sh_csi2_hwinit(struct sh_csi2 *priv)
        udelay(5);
        iowrite32(0x00000000, priv->base + SH_CSI2_SRST);
 
-       if (priv->client->lanes & 3)
-               tmp |= priv->client->lanes & 3;
-       else
-               /* Default - both lanes */
-               tmp |= 3;
+       switch (pdata->type) {
+       case SH_CSI2C:
+               if (priv->client->lanes == 1)
+                       tmp |= 1;
+               else
+                       /* Default - both lanes */
+                       tmp |= 3;
+               break;
+       case SH_CSI2I:
+               if (!priv->client->lanes || priv->client->lanes > 4)
+                       /* Default - all 4 lanes */
+                       tmp |= 0xf;
+               else
+                       tmp |= (1 << priv->client->lanes) - 1;
+       }
 
        if (priv->client->phy == SH_CSI2_PHY_MAIN)
                tmp |= 0x8000;
@@ -163,38 +198,18 @@ static void sh_csi2_hwinit(struct sh_csi2 *priv)
        iowrite32(tmp, priv->base + SH_CSI2_CHKSUM);
 }
 
-static int sh_csi2_set_bus_param(struct soc_camera_device *icd,
-                                unsigned long flags)
-{
-       return 0;
-}
-
-static unsigned long sh_csi2_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       const unsigned long flags = SOCAM_PCLK_SAMPLE_RISING |
-               SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
-               SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_DATA_ACTIVE_HIGH;
-
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
 static int sh_csi2_client_connect(struct sh_csi2 *priv)
 {
        struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
-       struct v4l2_subdev *sd, *csi2_sd = &priv->subdev;
-       struct soc_camera_device *icd = NULL;
+       struct soc_camera_device *icd = (struct soc_camera_device *)priv->subdev.grp_id;
+       struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
        struct device *dev = v4l2_get_subdevdata(&priv->subdev);
-       int i;
+       struct v4l2_mbus_config cfg;
+       unsigned long common_flags, csi2_flags;
+       int i, ret;
 
-       v4l2_device_for_each_subdev(sd, csi2_sd->v4l2_dev)
-               if (sd->grp_id) {
-                       icd = (struct soc_camera_device *)sd->grp_id;
-                       break;
-               }
-
-       if (!icd)
-               return -EINVAL;
+       if (priv->client)
+               return -EBUSY;
 
        for (i = 0; i < pdata->num_clients; i++)
                if (&pdata->clients[i].pdev->dev == icd->pdev)
@@ -205,14 +220,41 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv)
        if (i == pdata->num_clients)
                return -ENODEV;
 
-       priv->client = pdata->clients + i;
+       /* Check if we can support this camera */
+       csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_1_LANE;
+
+       switch (pdata->type) {
+       case SH_CSI2C:
+               if (pdata->clients[i].lanes != 1)
+                       csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
+               break;
+       case SH_CSI2I:
+               switch (pdata->clients[i].lanes) {
+               default:
+                       csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
+               case 3:
+                       csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
+               case 2:
+                       csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
+               }
+       }
 
-       priv->set_bus_param             = icd->ops->set_bus_param;
-       priv->query_bus_param           = icd->ops->query_bus_param;
-       icd->ops->set_bus_param         = sh_csi2_set_bus_param;
-       icd->ops->query_bus_param       = sh_csi2_query_bus_param;
+       cfg.type = V4L2_MBUS_CSI2;
+       ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &cfg);
+       if (ret == -ENOIOCTLCMD)
+               common_flags = csi2_flags;
+       else if (!ret)
+               common_flags = soc_mbus_config_compatible(&cfg,
+                                                         csi2_flags);
+       else
+               common_flags = 0;
 
-       csi2_sd->grp_id = (long)icd;
+       if (!common_flags)
+               return -EINVAL;
+
+       /* All good: camera MIPI configuration supported */
+       priv->mipi_flags = common_flags;
+       priv->client = pdata->clients + i;
 
        pm_runtime_get_sync(dev);
 
@@ -223,16 +265,10 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv)
 
 static void sh_csi2_client_disconnect(struct sh_csi2 *priv)
 {
-       struct soc_camera_device *icd = (struct soc_camera_device *)priv->subdev.grp_id;
+       if (!priv->client)
+               return;
 
        priv->client = NULL;
-       priv->subdev.grp_id = 0;
-
-       /* Driver is about to be unbound */
-       icd->ops->set_bus_param         = priv->set_bus_param;
-       icd->ops->query_bus_param       = priv->query_bus_param;
-       priv->set_bus_param             = NULL;
-       priv->query_bus_param           = NULL;
 
        pm_runtime_put(v4l2_get_subdevdata(&priv->subdev));
 }
index 5bdfe7e..b72580c 100644 (file)
@@ -50,49 +50,65 @@ static LIST_HEAD(hosts);
 static LIST_HEAD(devices);
 static DEFINE_MUTEX(list_lock);                /* Protects the list of hosts */
 
-static int soc_camera_power_set(struct soc_camera_device *icd,
-                               struct soc_camera_link *icl,
-                               int power_on)
+static int soc_camera_power_on(struct soc_camera_device *icd,
+                              struct soc_camera_link *icl)
 {
-       int ret;
-
-       if (power_on) {
-               ret = regulator_bulk_enable(icl->num_regulators,
-                                           icl->regulators);
-               if (ret < 0) {
-                       dev_err(icd->pdev, "Cannot enable regulators\n");
-                       return ret;
-               }
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       int ret = regulator_bulk_enable(icl->num_regulators,
+                                       icl->regulators);
+       if (ret < 0) {
+               dev_err(icd->pdev, "Cannot enable regulators\n");
+               return ret;
+       }
 
-               if (icl->power)
-                       ret = icl->power(icd->pdev, power_on);
+       if (icl->power) {
+               ret = icl->power(icd->pdev, 1);
                if (ret < 0) {
                        dev_err(icd->pdev,
                                "Platform failed to power-on the camera.\n");
-
-                       regulator_bulk_disable(icl->num_regulators,
-                                              icl->regulators);
-                       return ret;
+                       goto elinkpwr;
                }
-       } else {
-               ret = 0;
-               if (icl->power)
-                       ret = icl->power(icd->pdev, 0);
+       }
+
+       ret = v4l2_subdev_call(sd, core, s_power, 1);
+       if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+               goto esdpwr;
+
+       return 0;
+
+esdpwr:
+       if (icl->power)
+               icl->power(icd->pdev, 0);
+elinkpwr:
+       regulator_bulk_disable(icl->num_regulators,
+                              icl->regulators);
+       return ret;
+}
+
+static int soc_camera_power_off(struct soc_camera_device *icd,
+                               struct soc_camera_link *icl)
+{
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       int ret = v4l2_subdev_call(sd, core, s_power, 0);
+
+       if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+               return ret;
+
+       if (icl->power) {
+               ret = icl->power(icd->pdev, 0);
                if (ret < 0) {
                        dev_err(icd->pdev,
                                "Platform failed to power-off the camera.\n");
                        return ret;
                }
-
-               ret = regulator_bulk_disable(icl->num_regulators,
-                                            icl->regulators);
-               if (ret < 0) {
-                       dev_err(icd->pdev, "Cannot disable regulators\n");
-                       return ret;
-               }
        }
 
-       return 0;
+       ret = regulator_bulk_disable(icl->num_regulators,
+                                    icl->regulators);
+       if (ret < 0)
+               dev_err(icd->pdev, "Cannot disable regulators\n");
+
+       return ret;
 }
 
 const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
@@ -108,38 +124,38 @@ const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
 EXPORT_SYMBOL(soc_camera_xlate_by_fourcc);
 
 /**
- * soc_camera_apply_sensor_flags() - apply platform SOCAM_SENSOR_INVERT_* flags
+ * soc_camera_apply_board_flags() - apply platform SOCAM_SENSOR_INVERT_* flags
  * @icl:       camera platform parameters
- * @flags:     flags to be inverted according to platform configuration
+ * @cfg:       media bus configuration
  * @return:    resulting flags
  */
-unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
-                                           unsigned long flags)
+unsigned long soc_camera_apply_board_flags(struct soc_camera_link *icl,
+                                          const struct v4l2_mbus_config *cfg)
 {
-       unsigned long f;
+       unsigned long f, flags = cfg->flags;
 
        /* If only one of the two polarities is supported, switch to the opposite */
        if (icl->flags & SOCAM_SENSOR_INVERT_HSYNC) {
-               f = flags & (SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW);
-               if (f == SOCAM_HSYNC_ACTIVE_HIGH || f == SOCAM_HSYNC_ACTIVE_LOW)
-                       flags ^= SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW;
+               f = flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW);
+               if (f == V4L2_MBUS_HSYNC_ACTIVE_HIGH || f == V4L2_MBUS_HSYNC_ACTIVE_LOW)
+                       flags ^= V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW;
        }
 
        if (icl->flags & SOCAM_SENSOR_INVERT_VSYNC) {
-               f = flags & (SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW);
-               if (f == SOCAM_VSYNC_ACTIVE_HIGH || f == SOCAM_VSYNC_ACTIVE_LOW)
-                       flags ^= SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW;
+               f = flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW);
+               if (f == V4L2_MBUS_VSYNC_ACTIVE_HIGH || f == V4L2_MBUS_VSYNC_ACTIVE_LOW)
+                       flags ^= V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW;
        }
 
        if (icl->flags & SOCAM_SENSOR_INVERT_PCLK) {
-               f = flags & (SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING);
-               if (f == SOCAM_PCLK_SAMPLE_RISING || f == SOCAM_PCLK_SAMPLE_FALLING)
-                       flags ^= SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING;
+               f = flags & (V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING);
+               if (f == V4L2_MBUS_PCLK_SAMPLE_RISING || f == V4L2_MBUS_PCLK_SAMPLE_FALLING)
+                       flags ^= V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
        }
 
        return flags;
 }
-EXPORT_SYMBOL(soc_camera_apply_sensor_flags);
+EXPORT_SYMBOL(soc_camera_apply_board_flags);
 
 #define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
        ((x) >> 24) & 0xff
@@ -233,6 +249,14 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
        return v4l2_subdev_call(sd, core, s_std, *a);
 }
 
+static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a)
+{
+       struct soc_camera_device *icd = file->private_data;
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+
+       return v4l2_subdev_call(sd, core, g_std, a);
+}
+
 static int soc_camera_enum_fsizes(struct file *file, void *fh,
                                         struct v4l2_frmsizeenum *fsize)
 {
@@ -318,6 +342,32 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
                return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
 }
 
+static int soc_camera_create_bufs(struct file *file, void *priv,
+                           struct v4l2_create_buffers *create)
+{
+       struct soc_camera_device *icd = file->private_data;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+       /* videobuf2 only */
+       if (ici->ops->init_videobuf)
+               return -EINVAL;
+       else
+               return vb2_create_bufs(&icd->vb2_vidq, create);
+}
+
+static int soc_camera_prepare_buf(struct file *file, void *priv,
+                                 struct v4l2_buffer *b)
+{
+       struct soc_camera_device *icd = file->private_data;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+       /* videobuf2 only */
+       if (ici->ops->init_videobuf)
+               return -EINVAL;
+       else
+               return vb2_prepare_buf(&icd->vb2_vidq, b);
+}
+
 /* Always entered with .video_lock held */
 static int soc_camera_init_user_formats(struct soc_camera_device *icd)
 {
@@ -448,7 +498,7 @@ static int soc_camera_open(struct file *file)
        struct soc_camera_host *ici;
        int ret;
 
-       if (!icd->ops)
+       if (!to_soc_camera_control(icd))
                /* No device driver attached */
                return -ENODEV;
 
@@ -476,7 +526,7 @@ static int soc_camera_open(struct file *file)
                        },
                };
 
-               ret = soc_camera_power_set(icd, icl, 1);
+               ret = soc_camera_power_on(icd, icl);
                if (ret < 0)
                        goto epower;
 
@@ -512,6 +562,7 @@ static int soc_camera_open(struct file *file)
                        if (ret < 0)
                                goto einitvb;
                }
+               v4l2_ctrl_handler_setup(&icd->ctrl_handler);
        }
 
        file->private_data = icd;
@@ -529,7 +580,7 @@ esfmt:
 eresume:
        ici->ops->remove(icd);
 eiciadd:
-       soc_camera_power_set(icd, icl, 0);
+       soc_camera_power_off(icd, icl);
 epower:
        icd->use_count--;
        module_put(ici->ops->owner);
@@ -553,7 +604,7 @@ static int soc_camera_close(struct file *file)
                if (ici->ops->init_videobuf2)
                        vb2_queue_release(&icd->vb2_vidq);
 
-               soc_camera_power_set(icd, icl, 0);
+               soc_camera_power_off(icd, icl);
        }
 
        if (icd->streamer == file)
@@ -781,75 +832,6 @@ static int soc_camera_streamoff(struct file *file, void *priv,
        return 0;
 }
 
-static int soc_camera_queryctrl(struct file *file, void *priv,
-                               struct v4l2_queryctrl *qc)
-{
-       struct soc_camera_device *icd = file->private_data;
-       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-       int i;
-
-       WARN_ON(priv != file->private_data);
-
-       if (!qc->id)
-               return -EINVAL;
-
-       /* First check host controls */
-       for (i = 0; i < ici->ops->num_controls; i++)
-               if (qc->id == ici->ops->controls[i].id) {
-                       memcpy(qc, &(ici->ops->controls[i]),
-                               sizeof(*qc));
-                       return 0;
-               }
-
-       /* Then device controls */
-       for (i = 0; i < icd->ops->num_controls; i++)
-               if (qc->id == icd->ops->controls[i].id) {
-                       memcpy(qc, &(icd->ops->controls[i]),
-                               sizeof(*qc));
-                       return 0;
-               }
-
-       return -EINVAL;
-}
-
-static int soc_camera_g_ctrl(struct file *file, void *priv,
-                            struct v4l2_control *ctrl)
-{
-       struct soc_camera_device *icd = file->private_data;
-       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-       int ret;
-
-       WARN_ON(priv != file->private_data);
-
-       if (ici->ops->get_ctrl) {
-               ret = ici->ops->get_ctrl(icd, ctrl);
-               if (ret != -ENOIOCTLCMD)
-                       return ret;
-       }
-
-       return v4l2_subdev_call(sd, core, g_ctrl, ctrl);
-}
-
-static int soc_camera_s_ctrl(struct file *file, void *priv,
-                            struct v4l2_control *ctrl)
-{
-       struct soc_camera_device *icd = file->private_data;
-       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-       int ret;
-
-       WARN_ON(priv != file->private_data);
-
-       if (ici->ops->set_ctrl) {
-               ret = ici->ops->set_ctrl(icd, ctrl);
-               if (ret != -ENOIOCTLCMD)
-                       return ret;
-       }
-
-       return v4l2_subdev_call(sd, core, s_ctrl, ctrl);
-}
-
 static int soc_camera_cropcap(struct file *file, void *fh,
                              struct v4l2_cropcap *a)
 {
@@ -1003,7 +985,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
                goto ei2cga;
        }
 
-       icl->board_info->platform_data = icd;
+       icl->board_info->platform_data = icl;
 
        subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
                                icl->board_info, NULL);
@@ -1052,12 +1034,29 @@ static int soc_camera_probe(struct soc_camera_device *icd)
 
        dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev));
 
+       /*
+        * Currently the subdev with the largest number of controls (13) is
+        * ov6550. So let's pick 16 as a hint for the control handler. Note
+        * that this is a hint only: too large and you waste some memory, too
+        * small and there is a (very) small performance hit when looking up
+        * controls in the internal hash.
+        */
+       ret = v4l2_ctrl_handler_init(&icd->ctrl_handler, 16);
+       if (ret < 0)
+               return ret;
+
        ret = regulator_bulk_get(icd->pdev, icl->num_regulators,
                                 icl->regulators);
        if (ret < 0)
                goto ereg;
 
-       ret = soc_camera_power_set(icd, icl, 1);
+       /*
+        * This will not yet call v4l2_subdev_core_ops::s_power(1), because the
+        * subdevice has not been initialised yet. We'll have to call it once
+        * again after initialisation, even though it shouldn't be needed, we
+        * don't do any IO here.
+        */
+       ret = soc_camera_power_on(icd, icl);
        if (ret < 0)
                goto epower;
 
@@ -1098,6 +1097,7 @@ static int soc_camera_probe(struct soc_camera_device *icd)
                if (!control || !control->driver || !dev_get_drvdata(control) ||
                    !try_module_get(control->driver->owner)) {
                        icl->del_device(icd);
+                       ret = -ENODEV;
                        goto enodrv;
                }
        }
@@ -1105,6 +1105,9 @@ static int soc_camera_probe(struct soc_camera_device *icd)
        sd = soc_camera_to_subdev(icd);
        sd->grp_id = (long)icd;
 
+       if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler))
+               goto ectrl;
+
        /* At this point client .probe() should have run already */
        ret = soc_camera_init_user_formats(icd);
        if (ret < 0)
@@ -1123,6 +1126,10 @@ static int soc_camera_probe(struct soc_camera_device *icd)
        if (ret < 0)
                goto evidstart;
 
+       ret = v4l2_subdev_call(sd, core, s_power, 1);
+       if (ret < 0 && ret != -ENOIOCTLCMD)
+               goto esdpwr;
+
        /* Try to improve our guess of a reasonable window format */
        if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
                icd->user_width         = mf.width;
@@ -1133,16 +1140,19 @@ static int soc_camera_probe(struct soc_camera_device *icd)
 
        ici->ops->remove(icd);
 
-       soc_camera_power_set(icd, icl, 0);
+       soc_camera_power_off(icd, icl);
 
        mutex_unlock(&icd->video_lock);
 
        return 0;
 
+esdpwr:
+       video_unregister_device(icd->vdev);
 evidstart:
        mutex_unlock(&icd->video_lock);
        soc_camera_free_user_formats(icd);
 eiufmt:
+ectrl:
        if (icl->board_info) {
                soc_camera_free_i2c(icd);
        } else {
@@ -1152,13 +1162,15 @@ eiufmt:
 enodrv:
 eadddev:
        video_device_release(icd->vdev);
+       icd->vdev = NULL;
 evdc:
        ici->ops->remove(icd);
 eadd:
-       soc_camera_power_set(icd, icl, 0);
+       soc_camera_power_off(icd, icl);
 epower:
        regulator_bulk_free(icl->num_regulators, icl->regulators);
 ereg:
+       v4l2_ctrl_handler_free(&icd->ctrl_handler);
        return ret;
 }
 
@@ -1173,6 +1185,7 @@ static int soc_camera_remove(struct soc_camera_device *icd)
 
        BUG_ON(!icd->parent);
 
+       v4l2_ctrl_handler_free(&icd->ctrl_handler);
        if (vdev) {
                video_unregister_device(vdev);
                icd->vdev = NULL;
@@ -1363,24 +1376,24 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
 
 static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
        .vidioc_querycap         = soc_camera_querycap,
+       .vidioc_try_fmt_vid_cap  = soc_camera_try_fmt_vid_cap,
        .vidioc_g_fmt_vid_cap    = soc_camera_g_fmt_vid_cap,
-       .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
        .vidioc_s_fmt_vid_cap    = soc_camera_s_fmt_vid_cap,
+       .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
        .vidioc_enum_input       = soc_camera_enum_input,
        .vidioc_g_input          = soc_camera_g_input,
        .vidioc_s_input          = soc_camera_s_input,
        .vidioc_s_std            = soc_camera_s_std,
+       .vidioc_g_std            = soc_camera_g_std,
        .vidioc_enum_framesizes  = soc_camera_enum_fsizes,
        .vidioc_reqbufs          = soc_camera_reqbufs,
-       .vidioc_try_fmt_vid_cap  = soc_camera_try_fmt_vid_cap,
        .vidioc_querybuf         = soc_camera_querybuf,
        .vidioc_qbuf             = soc_camera_qbuf,
        .vidioc_dqbuf            = soc_camera_dqbuf,
+       .vidioc_create_bufs      = soc_camera_create_bufs,
+       .vidioc_prepare_buf      = soc_camera_prepare_buf,
        .vidioc_streamon         = soc_camera_streamon,
        .vidioc_streamoff        = soc_camera_streamoff,
-       .vidioc_queryctrl        = soc_camera_queryctrl,
-       .vidioc_g_ctrl           = soc_camera_g_ctrl,
-       .vidioc_s_ctrl           = soc_camera_s_ctrl,
        .vidioc_cropcap          = soc_camera_cropcap,
        .vidioc_g_crop           = soc_camera_g_crop,
        .vidioc_s_crop           = soc_camera_s_crop,
@@ -1409,6 +1422,7 @@ static int video_dev_create(struct soc_camera_device *icd)
        vdev->ioctl_ops         = &soc_camera_ioctl_ops;
        vdev->release           = video_device_release;
        vdev->tvnorms           = V4L2_STD_UNKNOWN;
+       vdev->ctrl_handler      = &icd->ctrl_handler;
        vdev->lock              = &icd->video_lock;
 
        icd->vdev = vdev;
@@ -1427,11 +1441,6 @@ static int soc_camera_video_start(struct soc_camera_device *icd)
        if (!icd->parent)
                return -ENODEV;
 
-       if (!icd->ops ||
-           !icd->ops->query_bus_param ||
-           !icd->ops->set_bus_param)
-               return -EINVAL;
-
        ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1);
        if (ret < 0) {
                dev_err(icd->pdev, "video_register_device failed: %d\n", ret);
index 8069cd6..4402a8a 100644 (file)
@@ -30,32 +30,12 @@ static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
        return container_of(subdev, struct soc_camera_platform_priv, subdev);
 }
 
-static struct soc_camera_platform_info *get_info(struct soc_camera_device *icd)
-{
-       struct platform_device *pdev =
-               to_platform_device(to_soc_camera_control(icd));
-       return pdev->dev.platform_data;
-}
-
 static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable)
 {
        struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
        return p->set_capture(p, enable);
 }
 
-static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
-                                            unsigned long flags)
-{
-       return 0;
-}
-
-static unsigned long
-soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
-{
-       struct soc_camera_platform_info *p = get_info(icd);
-       return p->bus_param;
-}
-
 static int soc_camera_platform_fill_fmt(struct v4l2_subdev *sd,
                                        struct v4l2_mbus_framefmt *mf)
 {
@@ -115,6 +95,17 @@ static int soc_camera_platform_cropcap(struct v4l2_subdev *sd,
        return 0;
 }
 
+static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd,
+                                            struct v4l2_mbus_config *cfg)
+{
+       struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
+
+       cfg->flags = p->mbus_param;
+       cfg->type = p->mbus_type;
+
+       return 0;
+}
+
 static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
        .s_stream       = soc_camera_platform_s_stream,
        .enum_mbus_fmt  = soc_camera_platform_enum_fmt,
@@ -123,6 +114,7 @@ static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
        .try_mbus_fmt   = soc_camera_platform_fill_fmt,
        .g_mbus_fmt     = soc_camera_platform_fill_fmt,
        .s_mbus_fmt     = soc_camera_platform_fill_fmt,
+       .g_mbus_config  = soc_camera_platform_g_mbus_config,
 };
 
 static struct v4l2_subdev_ops platform_subdev_ops = {
@@ -130,11 +122,6 @@ static struct v4l2_subdev_ops platform_subdev_ops = {
        .video  = &platform_subdev_video_ops,
 };
 
-static struct soc_camera_ops soc_camera_platform_ops = {
-       .set_bus_param          = soc_camera_platform_set_bus_param,
-       .query_bus_param        = soc_camera_platform_query_bus_param,
-};
-
 static int soc_camera_platform_probe(struct platform_device *pdev)
 {
        struct soc_camera_host *ici;
@@ -163,8 +150,6 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
        /* Set the control device reference */
        icd->control = &pdev->dev;
 
-       icd->ops = &soc_camera_platform_ops;
-
        ici = to_soc_camera_host(icd->parent);
 
        v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
@@ -178,7 +163,6 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
        return ret;
 
 evdrs:
-       icd->ops = NULL;
        platform_set_drvdata(pdev, NULL);
        kfree(priv);
        return ret;
@@ -187,11 +171,10 @@ evdrs:
 static int soc_camera_platform_remove(struct platform_device *pdev)
 {
        struct soc_camera_platform_priv *priv = get_priv(pdev);
-       struct soc_camera_platform_info *p = pdev->dev.platform_data;
-       struct soc_camera_device *icd = p->icd;
+       struct soc_camera_platform_info *p = v4l2_get_subdevdata(&priv->subdev);
 
+       p->icd->control = NULL;
        v4l2_device_unregister_subdev(&priv->subdev);
-       icd->ops = NULL;
        platform_set_drvdata(pdev, NULL);
        kfree(priv);
        return 0;
index bea7c9c..cf7f219 100644 (file)
@@ -383,6 +383,39 @@ const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
 }
 EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
 
+unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
+                                       unsigned int flags)
+{
+       unsigned long common_flags;
+       bool hsync = true, vsync = true, pclk, data, mode;
+       bool mipi_lanes, mipi_clock;
+
+       common_flags = cfg->flags & flags;
+
+       switch (cfg->type) {
+       case V4L2_MBUS_PARALLEL:
+               hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+                                       V4L2_MBUS_HSYNC_ACTIVE_LOW);
+               vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+                                       V4L2_MBUS_VSYNC_ACTIVE_LOW);
+       case V4L2_MBUS_BT656:
+               pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
+                                      V4L2_MBUS_PCLK_SAMPLE_FALLING);
+               data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
+                                      V4L2_MBUS_DATA_ACTIVE_LOW);
+               mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
+               return (!hsync || !vsync || !pclk || !data || !mode) ?
+                       0 : common_flags;
+       case V4L2_MBUS_CSI2:
+               mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
+               mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
+                                            V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
+               return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
+       }
+       return 0;
+}
+EXPORT_SYMBOL(soc_mbus_config_compatible);
+
 static int __init soc_mbus_init(void)
 {
        return 0;
index 742482e..a514fa6 100644 (file)
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/v4l2-mediabus.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-subdev.h>
+
 #include <media/soc_camera.h>
 #include <media/tw9910.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-subdev.h>
 
 #define GET_ID(val)  ((val & 0xF8) >> 3)
 #define GET_REV(val) (val & 0x07)
 #define RTSEL_FIELD 0x06 /* 0110 = FIELD */
 #define RTSEL_RTCO  0x07 /* 0111 = RTCO ( Real Time Control ) */
 
+/* HSYNC start and end are constant for now */
+#define HSYNC_START    0x0260
+#define HSYNC_END      0x0300
+
 /*
  * structure
  */
@@ -220,22 +226,11 @@ struct tw9910_scale_ctrl {
        u16             vscale;
 };
 
-struct tw9910_cropping_ctrl {
-       u16 vdelay;
-       u16 vactive;
-       u16 hdelay;
-       u16 hactive;
-};
-
-struct tw9910_hsync_ctrl {
-       u16 start;
-       u16 end;
-};
-
 struct tw9910_priv {
        struct v4l2_subdev              subdev;
        struct tw9910_video_info        *info;
        const struct tw9910_scale_ctrl  *scale;
+       v4l2_std_id                     norm;
        u32                             revision;
 };
 
@@ -329,11 +324,6 @@ static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
        },
 };
 
-static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
-       .start = 0x0260,
-       .end   = 0x0300,
-};
-
 /*
  * general function
  */
@@ -378,21 +368,20 @@ static int tw9910_set_scale(struct i2c_client *client,
        return ret;
 }
 
-static int tw9910_set_hsync(struct i2c_client *client,
-                           const struct tw9910_hsync_ctrl *hsync)
+static int tw9910_set_hsync(struct i2c_client *client)
 {
        struct tw9910_priv *priv = to_tw9910(client);
        int ret;
 
        /* bit 10 - 3 */
        ret = i2c_smbus_write_byte_data(client, HSBEGIN,
-                                       (hsync->start & 0x07F8) >> 3);
+                                       (HSYNC_START & 0x07F8) >> 3);
        if (ret < 0)
                return ret;
 
        /* bit 10 - 3 */
        ret = i2c_smbus_write_byte_data(client, HSEND,
-                                       (hsync->end & 0x07F8) >> 3);
+                                       (HSYNC_END & 0x07F8) >> 3);
        if (ret < 0)
                return ret;
 
@@ -400,8 +389,8 @@ static int tw9910_set_hsync(struct i2c_client *client,
        /* bit 2 - 0 */
        if (1 == priv->revision)
                ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
-                                     (hsync->start & 0x0007) << 4 |
-                                     (hsync->end   & 0x0007));
+                                     (HSYNC_START & 0x0007) << 4 |
+                                     (HSYNC_END   & 0x0007));
 
        return ret;
 }
@@ -433,12 +422,11 @@ static int tw9910_power(struct i2c_client *client, int enable)
        return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
 }
 
-static const struct tw9910_scale_ctrl*
-tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
+static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm,
+                                                         u32 width, u32 height)
 {
        const struct tw9910_scale_ctrl *scale;
        const struct tw9910_scale_ctrl *ret = NULL;
-       v4l2_std_id norm = icd->vdev->current_norm;
        __u32 diff = 0xffffffff, tmp;
        int size, i;
 
@@ -465,7 +453,7 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
 }
 
 /*
- * soc_camera_ops function
+ * subdevice operations
  */
 static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
 {
@@ -507,49 +495,27 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
        return tw9910_power(client, enable);
 }
 
-static int tw9910_set_bus_param(struct soc_camera_device *icd,
-                               unsigned long flags)
+static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
 {
-       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       u8 val = VSSL_VVALID | HSSL_DVALID;
+       struct tw9910_priv *priv = to_tw9910(client);
 
-       /*
-        * set OUTCTR1
-        *
-        * We use VVALID and DVALID signals to control VSYNC and HSYNC
-        * outputs, in this mode their polarity is inverted.
-        */
-       if (flags & SOCAM_HSYNC_ACTIVE_LOW)
-               val |= HSP_HI;
+       *norm = priv->norm;
 
-       if (flags & SOCAM_VSYNC_ACTIVE_LOW)
-               val |= VSP_HI;
-
-       return i2c_smbus_write_byte_data(client, OUTCTR1, val);
+       return 0;
 }
 
-static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
+static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
 {
-       struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct tw9910_priv *priv = to_tw9910(client);
-       struct soc_camera_link *icl = to_soc_camera_link(icd);
-       unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
-               SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
-               SOCAM_VSYNC_ACTIVE_LOW  | SOCAM_HSYNC_ACTIVE_LOW  |
-               SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
 
-       return soc_camera_apply_sensor_flags(icl, flags);
-}
-
-static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
-       int ret = -EINVAL;
+       if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
+               return -EINVAL;
 
-       if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL))
-               ret = 0;
+       priv->norm = norm;
 
-       return ret;
+       return 0;
 }
 
 static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
@@ -600,19 +566,17 @@ static int tw9910_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
-static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
 {
-       struct v4l2_rect *rect = &a->c;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct tw9910_priv *priv = to_tw9910(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
-       int                 ret  = -EINVAL;
-       u8                  val;
+       int ret = -EINVAL;
+       u8 val;
 
        /*
         * select suitable norm
         */
-       priv->scale = tw9910_select_norm(icd, rect->width, rect->height);
+       priv->scale = tw9910_select_norm(priv->norm, *width, *height);
        if (!priv->scale)
                goto tw9910_set_fmt_error;
 
@@ -670,14 +634,12 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
        /*
         * set hsync
         */
-       ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl);
+       ret = tw9910_set_hsync(client);
        if (ret < 0)
                goto tw9910_set_fmt_error;
 
-       rect->width = priv->scale->width;
-       rect->height = priv->scale->height;
-       rect->left = 0;
-       rect->top = 0;
+       *width = priv->scale->width;
+       *height = priv->scale->height;
 
        return ret;
 
@@ -694,25 +656,15 @@ static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        struct tw9910_priv *priv = to_tw9910(client);
 
-       if (!priv->scale) {
-               int ret;
-               struct v4l2_crop crop = {
-                       .c = {
-                               .left   = 0,
-                               .top    = 0,
-                               .width  = 640,
-                               .height = 480,
-                       },
-               };
-               ret = tw9910_s_crop(sd, &crop);
-               if (ret < 0)
-                       return ret;
-       }
-
        a->c.left       = 0;
        a->c.top        = 0;
-       a->c.width      = priv->scale->width;
-       a->c.height     = priv->scale->height;
+       if (priv->norm & V4L2_STD_NTSC) {
+               a->c.width      = 640;
+               a->c.height     = 480;
+       } else {
+               a->c.width      = 768;
+               a->c.height     = 576;
+       }
        a->type         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
        return 0;
@@ -720,14 +672,19 @@ static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 
 static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 {
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct tw9910_priv *priv = to_tw9910(client);
+
        a->bounds.left                  = 0;
        a->bounds.top                   = 0;
-       a->bounds.width                 = 768;
-       a->bounds.height                = 576;
-       a->defrect.left                 = 0;
-       a->defrect.top                  = 0;
-       a->defrect.width                = 640;
-       a->defrect.height               = 480;
+       if (priv->norm & V4L2_STD_NTSC) {
+               a->bounds.width         = 640;
+               a->bounds.height        = 480;
+       } else {
+               a->bounds.width         = 768;
+               a->bounds.height        = 576;
+       }
+       a->defrect                      = a->bounds;
        a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        a->pixelaspect.numerator        = 1;
        a->pixelaspect.denominator      = 1;
@@ -743,15 +700,8 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
 
        if (!priv->scale) {
                int ret;
-               struct v4l2_crop crop = {
-                       .c = {
-                               .left   = 0,
-                               .top    = 0,
-                               .width  = 640,
-                               .height = 480,
-                       },
-               };
-               ret = tw9910_s_crop(sd, &crop);
+               u32 width = 640, height = 480;
+               ret = tw9910_set_frame(sd, &width, &height);
                if (ret < 0)
                        return ret;
        }
@@ -768,17 +718,7 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
 static int tw9910_s_fmt(struct v4l2_subdev *sd,
                        struct v4l2_mbus_framefmt *mf)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct tw9910_priv *priv = to_tw9910(client);
-       /* See tw9910_s_crop() - no proper cropping support */
-       struct v4l2_crop a = {
-               .c = {
-                       .left   = 0,
-                       .top    = 0,
-                       .width  = mf->width,
-                       .height = mf->height,
-               },
-       };
+       u32 width = mf->width, height = mf->height;
        int ret;
 
        WARN_ON(mf->field != V4L2_FIELD_ANY &&
@@ -792,10 +732,10 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd,
 
        mf->colorspace = V4L2_COLORSPACE_JPEG;
 
-       ret = tw9910_s_crop(sd, &a);
+       ret = tw9910_set_frame(sd, &width, &height);
        if (!ret) {
-               mf->width       = priv->scale->width;
-               mf->height      = priv->scale->height;
+               mf->width       = width;
+               mf->height      = height;
        }
        return ret;
 }
@@ -804,7 +744,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
                          struct v4l2_mbus_framefmt *mf)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
-       struct soc_camera_device *icd = client->dev.platform_data;
+       struct tw9910_priv *priv = to_tw9910(client);
        const struct tw9910_scale_ctrl *scale;
 
        if (V4L2_FIELD_ANY == mf->field) {
@@ -820,7 +760,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
        /*
         * select suitable norm
         */
-       scale = tw9910_select_norm(icd, mf->width, mf->height);
+       scale = tw9910_select_norm(priv->norm, mf->width, mf->height);
        if (!scale)
                return -EINVAL;
 
@@ -830,16 +770,11 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
        return 0;
 }
 
-static int tw9910_video_probe(struct soc_camera_device *icd,
-                             struct i2c_client *client)
+static int tw9910_video_probe(struct i2c_client *client)
 {
        struct tw9910_priv *priv = to_tw9910(client);
        s32 id;
 
-       /* We must have a parent by now. And it cannot be a wrong one. */
-       BUG_ON(!icd->parent ||
-              to_soc_camera_host(icd->parent)->nr != icd->iface);
-
        /*
         * tw9910 only use 8 or 16 bit bus width
         */
@@ -868,20 +803,15 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
        dev_info(&client->dev,
                 "tw9910 Product ID %0x:%0x\n", id, priv->revision);
 
-       icd->vdev->tvnorms      = V4L2_STD_NTSC | V4L2_STD_PAL;
-       icd->vdev->current_norm = V4L2_STD_NTSC;
+       priv->norm = V4L2_STD_NTSC;
 
        return 0;
 }
 
-static struct soc_camera_ops tw9910_ops = {
-       .set_bus_param          = tw9910_set_bus_param,
-       .query_bus_param        = tw9910_query_bus_param,
-};
-
 static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
        .g_chip_ident   = tw9910_g_chip_ident,
        .s_std          = tw9910_s_std,
+       .g_std          = tw9910_g_std,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .g_register     = tw9910_g_register,
        .s_register     = tw9910_s_register,
@@ -898,6 +828,45 @@ static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
        return 0;
 }
 
+static int tw9910_g_mbus_config(struct v4l2_subdev *sd,
+                               struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
+               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
+               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
+               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->flags = soc_camera_apply_board_flags(icl, cfg);
+
+       return 0;
+}
+
+static int tw9910_s_mbus_config(struct v4l2_subdev *sd,
+                               const struct v4l2_mbus_config *cfg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+       u8 val = VSSL_VVALID | HSSL_DVALID;
+       unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
+
+       /*
+        * set OUTCTR1
+        *
+        * We use VVALID and DVALID signals to control VSYNC and HSYNC
+        * outputs, in this mode their polarity is inverted.
+        */
+       if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+               val |= HSP_HI;
+
+       if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+               val |= VSP_HI;
+
+       return i2c_smbus_write_byte_data(client, OUTCTR1, val);
+}
+
 static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
        .s_stream       = tw9910_s_stream,
        .g_mbus_fmt     = tw9910_g_fmt,
@@ -905,8 +874,9 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
        .try_mbus_fmt   = tw9910_try_fmt,
        .cropcap        = tw9910_cropcap,
        .g_crop         = tw9910_g_crop,
-       .s_crop         = tw9910_s_crop,
        .enum_mbus_fmt  = tw9910_enum_fmt,
+       .g_mbus_config  = tw9910_g_mbus_config,
+       .s_mbus_config  = tw9910_s_mbus_config,
 };
 
 static struct v4l2_subdev_ops tw9910_subdev_ops = {
@@ -922,23 +892,18 @@ static int tw9910_probe(struct i2c_client *client,
                        const struct i2c_device_id *did)
 
 {
-       struct tw9910_priv             *priv;
-       struct tw9910_video_info       *info;
-       struct soc_camera_device       *icd = client->dev.platform_data;
-       struct i2c_adapter             *adapter =
+       struct tw9910_priv              *priv;
+       struct tw9910_video_info        *info;
+       struct i2c_adapter              *adapter =
                to_i2c_adapter(client->dev.parent);
-       struct soc_camera_link         *icl;
-       int                             ret;
+       struct soc_camera_link          *icl = soc_camera_i2c_to_link(client);
+       int                             ret;
 
-       if (!icd) {
-               dev_err(&client->dev, "TW9910: missing soc-camera data!\n");
+       if (!icl || !icl->priv) {
+               dev_err(&client->dev, "TW9910: missing platform data!\n");
                return -EINVAL;
        }
 
-       icl = to_soc_camera_link(icd);
-       if (!icl || !icl->priv)
-               return -EINVAL;
-
        info = icl->priv;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -956,14 +921,9 @@ static int tw9910_probe(struct i2c_client *client,
 
        v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
 
-       icd->ops     = &tw9910_ops;
-       icd->iface   = icl->bus_id;
-
-       ret = tw9910_video_probe(icd, client);
-       if (ret) {
-               icd->ops = NULL;
+       ret = tw9910_video_probe(client);
+       if (ret)
                kfree(priv);
-       }
 
        return ret;
 }
@@ -971,9 +931,7 @@ static int tw9910_probe(struct i2c_client *client,
 static int tw9910_remove(struct i2c_client *client)
 {
        struct tw9910_priv *priv = to_tw9910(client);
-       struct soc_camera_device *icd = client->dev.platform_data;
 
-       icd->ops = NULL;
        kfree(priv);
        return 0;
 }
index 61979b7..c68531b 100644 (file)
@@ -159,11 +159,25 @@ struct v4l2_format32 {
        } fmt;
 };
 
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+/**
+ * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument
+ * @index:     on return, index of the first created buffer
+ * @count:     entry: number of requested buffers,
+ *             return: number of created buffers
+ * @memory:    buffer memory type
+ * @format:    frame format, for which buffers are requested
+ * @reserved:  future extensions
+ */
+struct v4l2_create_buffers32 {
+       __u32                   index;
+       __u32                   count;
+       enum v4l2_memory        memory;
+       struct v4l2_format32    format;
+       __u32                   reserved[8];
+};
+
+static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
-                       get_user(kp->type, &up->type))
-                       return -EFAULT;
        switch (kp->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +206,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
        }
 }
 
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
+                       get_user(kp->type, &up->type))
+                       return -EFAULT;
+       return __get_v4l2_format32(kp, up);
+}
+
+static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
+           copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
+                       return -EFAULT;
+       return __get_v4l2_format32(&kp->format, &up->format);
+}
+
+static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
-               put_user(kp->type, &up->type))
-               return -EFAULT;
        switch (kp->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +252,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
        }
 }
 
+static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
+               put_user(kp->type, &up->type))
+               return -EFAULT;
+       return __put_v4l2_format32(kp, up);
+}
+
+static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+{
+       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+           copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
+                       return -EFAULT;
+       return __put_v4l2_format32(&kp->format, &up->format);
+}
+
 struct v4l2_standard32 {
        __u32                index;
        __u32                id[2]; /* __u64 would get the alignment wrong */
@@ -702,6 +745,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
 #define        VIDIOC_DQEVENT32        _IOR ('V', 89, struct v4l2_event32)
+#define VIDIOC_CREATE_BUFS32   _IOWR('V', 92, struct v4l2_create_buffers32)
+#define VIDIOC_PREPARE_BUF32   _IOWR('V', 93, struct v4l2_buffer32)
 
 #define VIDIOC_OVERLAY32       _IOW ('V', 14, s32)
 #define VIDIOC_STREAMON32      _IOW ('V', 18, s32)
@@ -721,6 +766,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
                struct v4l2_standard v2s;
                struct v4l2_ext_controls v2ecs;
                struct v4l2_event v2ev;
+               struct v4l2_create_buffers v2crt;
                unsigned long vx;
                int vi;
        } karg;
@@ -751,6 +797,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
        case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
        case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
        case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
+       case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
+       case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
        }
 
        switch (cmd) {
@@ -775,6 +823,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
                compatible_arg = 0;
                break;
 
+       case VIDIOC_CREATE_BUFS:
+               err = get_v4l2_create32(&karg.v2crt, up);
+               compatible_arg = 0;
+               break;
+
+       case VIDIOC_PREPARE_BUF:
        case VIDIOC_QUERYBUF:
        case VIDIOC_QBUF:
        case VIDIOC_DQBUF:
@@ -860,6 +914,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
                err = put_v4l2_format32(&karg.v2f, up);
                break;
 
+       case VIDIOC_CREATE_BUFS:
+               err = put_v4l2_create32(&karg.v2crt, up);
+               break;
+
        case VIDIOC_QUERYBUF:
        case VIDIOC_QBUF:
        case VIDIOC_DQBUF:
@@ -959,6 +1017,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
        case VIDIOC_DQEVENT32:
        case VIDIOC_SUBSCRIBE_EVENT:
        case VIDIOC_UNSUBSCRIBE_EVENT:
+       case VIDIOC_CREATE_BUFS32:
+       case VIDIOC_PREPARE_BUF32:
                ret = do_video_ioctl(file, cmd, arg);
                break;
 
index fc8666a..5552f81 100644 (file)
@@ -210,6 +210,7 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
                "Disabled",
                "50 Hz",
                "60 Hz",
+               "Auto",
                NULL
        };
        static const char * const camera_exposure_auto[] = {
index e6a2c3b..9fc0ae8 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/types.h>
 #include <linux/ioctl.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #if defined(CONFIG_SPI)
 #include <linux/spi/spi.h>
 #endif
@@ -193,6 +194,13 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
 }
 EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
 
+static void v4l2_device_release_subdev_node(struct video_device *vdev)
+{
+       struct v4l2_subdev *sd = video_get_drvdata(vdev);
+       sd->devnode = NULL;
+       kfree(vdev);
+}
+
 int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
 {
        struct video_device *vdev;
@@ -206,22 +214,40 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
                if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
                        continue;
 
-               vdev = &sd->devnode;
+               vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
+               if (!vdev) {
+                       err = -ENOMEM;
+                       goto clean_up;
+               }
+
+               video_set_drvdata(vdev, sd);
                strlcpy(vdev->name, sd->name, sizeof(vdev->name));
                vdev->v4l2_dev = v4l2_dev;
                vdev->fops = &v4l2_subdev_fops;
-               vdev->release = video_device_release_empty;
+               vdev->release = v4l2_device_release_subdev_node;
                vdev->ctrl_handler = sd->ctrl_handler;
                err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
                                              sd->owner);
-               if (err < 0)
-                       return err;
+               if (err < 0) {
+                       kfree(vdev);
+                       goto clean_up;
+               }
 #if defined(CONFIG_MEDIA_CONTROLLER)
                sd->entity.v4l.major = VIDEO_MAJOR;
                sd->entity.v4l.minor = vdev->minor;
 #endif
+               sd->devnode = vdev;
        }
        return 0;
+
+clean_up:
+       list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
+               if (!sd->devnode)
+                       break;
+               video_unregister_device(sd->devnode);
+       }
+
+       return err;
 }
 EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
 
@@ -247,7 +273,7 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
        if (v4l2_dev->mdev)
                media_device_unregister_entity(&sd->entity);
 #endif
-       video_unregister_device(&sd->devnode);
+       video_unregister_device(sd->devnode);
        module_put(sd->owner);
 }
 EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
index 24fd433..e1da8fc 100644 (file)
@@ -273,6 +273,8 @@ static const char *v4l2_ioctls[] = {
        [_IOC_NR(VIDIOC_DQEVENT)]          = "VIDIOC_DQEVENT",
        [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)]  = "VIDIOC_SUBSCRIBE_EVENT",
        [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
+       [_IOC_NR(VIDIOC_CREATE_BUFS)]      = "VIDIOC_CREATE_BUFS",
+       [_IOC_NR(VIDIOC_PREPARE_BUF)]      = "VIDIOC_PREPARE_BUF",
 };
 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
 
@@ -2104,6 +2106,40 @@ static long __video_do_ioctl(struct file *file,
                dbgarg(cmd, "type=0x%8.8x", sub->type);
                break;
        }
+       case VIDIOC_CREATE_BUFS:
+       {
+               struct v4l2_create_buffers *create = arg;
+
+               if (!ops->vidioc_create_bufs)
+                       break;
+               if (ret_prio) {
+                       ret = ret_prio;
+                       break;
+               }
+               ret = check_fmt(ops, create->format.type);
+               if (ret)
+                       break;
+
+               ret = ops->vidioc_create_bufs(file, fh, create);
+
+               dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
+               break;
+       }
+       case VIDIOC_PREPARE_BUF:
+       {
+               struct v4l2_buffer *b = arg;
+
+               if (!ops->vidioc_prepare_buf)
+                       break;
+               ret = check_fmt(ops, b->type);
+               if (ret)
+                       break;
+
+               ret = ops->vidioc_prepare_buf(file, fh, b);
+
+               dbgarg(cmd, "index=%d", b->index);
+               break;
+       }
        default:
                if (!ops->vidioc_default)
                        break;
index 3f5c7a3..979e544 100644 (file)
@@ -38,7 +38,8 @@ module_param(debug, int, 0644);
        (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
 
 #define V4L2_BUFFER_STATE_FLAGS        (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
-                                V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR)
+                                V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
+                                V4L2_BUF_FLAG_PREPARED)
 
 /**
  * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
@@ -109,13 +110,22 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
  * __setup_offsets() - setup unique offsets ("cookies") for every plane in
  * every buffer on the queue
  */
-static void __setup_offsets(struct vb2_queue *q)
+static void __setup_offsets(struct vb2_queue *q, unsigned int n)
 {
        unsigned int buffer, plane;
        struct vb2_buffer *vb;
-       unsigned long off = 0;
+       unsigned long off;
 
-       for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+       if (q->num_buffers) {
+               struct v4l2_plane *p;
+               vb = q->bufs[q->num_buffers - 1];
+               p = &vb->v4l2_planes[vb->num_planes - 1];
+               off = PAGE_ALIGN(p->m.mem_offset + p->length);
+       } else {
+               off = 0;
+       }
+
+       for (buffer = q->num_buffers; buffer < q->num_buffers + n; ++buffer) {
                vb = q->bufs[buffer];
                if (!vb)
                        continue;
@@ -161,7 +171,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
                vb->state = VB2_BUF_STATE_DEQUEUED;
                vb->vb2_queue = q;
                vb->num_planes = num_planes;
-               vb->v4l2_buf.index = buffer;
+               vb->v4l2_buf.index = q->num_buffers + buffer;
                vb->v4l2_buf.type = q->type;
                vb->v4l2_buf.memory = memory;
 
@@ -189,15 +199,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
                        }
                }
 
-               q->bufs[buffer] = vb;
+               q->bufs[q->num_buffers + buffer] = vb;
        }
 
-       q->num_buffers = buffer;
-
-       __setup_offsets(q);
+       __setup_offsets(q, buffer);
 
        dprintk(1, "Allocated %d buffers, %d plane(s) each\n",
-                       q->num_buffers, num_planes);
+                       buffer, num_planes);
 
        return buffer;
 }
@@ -205,12 +213,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
 /**
  * __vb2_free_mem() - release all video buffer memory for a given queue
  */
-static void __vb2_free_mem(struct vb2_queue *q)
+static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
 {
        unsigned int buffer;
        struct vb2_buffer *vb;
 
-       for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+       for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
+            ++buffer) {
                vb = q->bufs[buffer];
                if (!vb)
                        continue;
@@ -224,17 +233,18 @@ static void __vb2_free_mem(struct vb2_queue *q)
 }
 
 /**
- * __vb2_queue_free() - free the queue - video memory and related information
- * and return the queue to an uninitialized state. Might be called even if the
- * queue has already been freed.
+ * __vb2_queue_free() - free buffers at the end of the queue - video memory and
+ * related information, if no buffers are left return the queue to an
+ * uninitialized state. Might be called even if the queue has already been freed.
  */
-static void __vb2_queue_free(struct vb2_queue *q)
+static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
 {
        unsigned int buffer;
 
        /* Call driver-provided cleanup function for each buffer, if provided */
        if (q->ops->buf_cleanup) {
-               for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+               for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
+                    ++buffer) {
                        if (NULL == q->bufs[buffer])
                                continue;
                        q->ops->buf_cleanup(q->bufs[buffer]);
@@ -242,23 +252,25 @@ static void __vb2_queue_free(struct vb2_queue *q)
        }
 
        /* Release video buffer memory */
-       __vb2_free_mem(q);
+       __vb2_free_mem(q, buffers);
 
        /* Free videobuf buffers */
-       for (buffer = 0; buffer < q->num_buffers; ++buffer) {
+       for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
+            ++buffer) {
                kfree(q->bufs[buffer]);
                q->bufs[buffer] = NULL;
        }
 
-       q->num_buffers = 0;
-       q->memory = 0;
+       q->num_buffers -= buffers;
+       if (!q->num_buffers)
+               q->memory = 0;
 }
 
 /**
  * __verify_planes_array() - verify that the planes array passed in struct
  * v4l2_buffer from userspace can be safely used
  */
-static int __verify_planes_array(struct vb2_buffer *vb, struct v4l2_buffer *b)
+static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 {
        /* Is memory for copying plane information present? */
        if (NULL == b->m.planes) {
@@ -318,7 +330,7 @@ static bool __buffers_in_use(struct vb2_queue *q)
 static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
 {
        struct vb2_queue *q = vb->vb2_queue;
-       int ret = 0;
+       int ret;
 
        /* Copy back data such as timestamp, flags, input, etc. */
        memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
@@ -365,6 +377,9 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
        case VB2_BUF_STATE_DONE:
                b->flags |= V4L2_BUF_FLAG_DONE;
                break;
+       case VB2_BUF_STATE_PREPARED:
+               b->flags |= V4L2_BUF_FLAG_PREPARED;
+               break;
        case VB2_BUF_STATE_DEQUEUED:
                /* nothing */
                break;
@@ -373,7 +388,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
        if (__buffer_in_use(q, vb))
                b->flags |= V4L2_BUF_FLAG_MAPPED;
 
-       return ret;
+       return 0;
 }
 
 /**
@@ -459,7 +474,7 @@ static int __verify_mmap_ops(struct vb2_queue *q)
  */
 int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
 {
-       unsigned int num_buffers, num_planes;
+       unsigned int num_buffers, allocated_buffers, num_planes = 0;
        int ret = 0;
 
        if (q->fileio) {
@@ -507,7 +522,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
                        return -EBUSY;
                }
 
-               __vb2_queue_free(q);
+               __vb2_queue_free(q, q->num_buffers);
 
                /*
                 * In case of REQBUFS(0) return immediately without calling
@@ -529,7 +544,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
         * Ask the driver how many buffers and planes per buffer it requires.
         * Driver also sets the size and allocator context for each plane.
         */
-       ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
+       ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes,
                       q->plane_sizes, q->alloc_ctx);
        if (ret)
                return ret;
@@ -541,43 +556,167 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
                return -ENOMEM;
        }
 
+       allocated_buffers = ret;
+
        /*
         * Check if driver can handle the allocated number of buffers.
         */
-       if (ret < num_buffers) {
-               unsigned int orig_num_buffers;
+       if (allocated_buffers < num_buffers) {
+               num_buffers = allocated_buffers;
 
-               orig_num_buffers = num_buffers = ret;
-               ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
-                              q->plane_sizes, q->alloc_ctx);
-               if (ret)
-                       goto free_mem;
+               ret = call_qop(q, queue_setup, q, NULL, &num_buffers,
+                              &num_planes, q->plane_sizes, q->alloc_ctx);
 
-               if (orig_num_buffers < num_buffers) {
+               if (!ret && allocated_buffers < num_buffers)
                        ret = -ENOMEM;
-                       goto free_mem;
-               }
 
                /*
-                * Ok, driver accepted smaller number of buffers.
+                * Either the driver has accepted a smaller number of buffers,
+                * or .queue_setup() returned an error
                 */
-               ret = num_buffers;
+       }
+
+       q->num_buffers = allocated_buffers;
+
+       if (ret < 0) {
+               __vb2_queue_free(q, allocated_buffers);
+               return ret;
        }
 
        /*
         * Return the number of successfully allocated buffers
         * to the userspace.
         */
-       req->count = ret;
+       req->count = allocated_buffers;
 
        return 0;
-
-free_mem:
-       __vb2_queue_free(q);
-       return ret;
 }
 EXPORT_SYMBOL_GPL(vb2_reqbufs);
 
+/**
+ * vb2_create_bufs() - Allocate buffers and any required auxiliary structs
+ * @q:         videobuf2 queue
+ * @create:    creation parameters, passed from userspace to vidioc_create_bufs
+ *             handler in driver
+ *
+ * Should be called from vidioc_create_bufs ioctl handler of a driver.
+ * This function:
+ * 1) verifies parameter sanity
+ * 2) calls the .queue_setup() queue operation
+ * 3) performs any necessary memory allocations
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_create_bufs handler in driver.
+ */
+int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
+{
+       unsigned int num_planes = 0, num_buffers, allocated_buffers;
+       int ret = 0;
+
+       if (q->fileio) {
+               dprintk(1, "%s(): file io in progress\n", __func__);
+               return -EBUSY;
+       }
+
+       if (create->memory != V4L2_MEMORY_MMAP
+                       && create->memory != V4L2_MEMORY_USERPTR) {
+               dprintk(1, "%s(): unsupported memory type\n", __func__);
+               return -EINVAL;
+       }
+
+       if (create->format.type != q->type) {
+               dprintk(1, "%s(): requested type is incorrect\n", __func__);
+               return -EINVAL;
+       }
+
+       /*
+        * Make sure all the required memory ops for given memory type
+        * are available.
+        */
+       if (create->memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) {
+               dprintk(1, "%s(): MMAP for current setup unsupported\n", __func__);
+               return -EINVAL;
+       }
+
+       if (create->memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
+               dprintk(1, "%s(): USERPTR for current setup unsupported\n", __func__);
+               return -EINVAL;
+       }
+
+       if (q->num_buffers == VIDEO_MAX_FRAME) {
+               dprintk(1, "%s(): maximum number of buffers already allocated\n",
+                       __func__);
+               return -ENOBUFS;
+       }
+
+       create->index = q->num_buffers;
+
+       if (!q->num_buffers) {
+               memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
+               memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
+               q->memory = create->memory;
+       }
+
+       num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers);
+
+       /*
+        * Ask the driver, whether the requested number of buffers, planes per
+        * buffer and their sizes are acceptable
+        */
+       ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
+                      &num_planes, q->plane_sizes, q->alloc_ctx);
+       if (ret)
+               return ret;
+
+       /* Finally, allocate buffers and video memory */
+       ret = __vb2_queue_alloc(q, create->memory, num_buffers,
+                               num_planes);
+       if (ret < 0) {
+               dprintk(1, "Memory allocation failed with error: %d\n", ret);
+               return ret;
+       }
+
+       allocated_buffers = ret;
+
+       /*
+        * Check if driver can handle the so far allocated number of buffers.
+        */
+       if (ret < num_buffers) {
+               num_buffers = ret;
+
+               /*
+                * q->num_buffers contains the total number of buffers, that the
+                * queue driver has set up
+                */
+               ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
+                              &num_planes, q->plane_sizes, q->alloc_ctx);
+
+               if (!ret && allocated_buffers < num_buffers)
+                       ret = -ENOMEM;
+
+               /*
+                * Either the driver has accepted a smaller number of buffers,
+                * or .queue_setup() returned an error
+                */
+       }
+
+       q->num_buffers += allocated_buffers;
+
+       if (ret < 0) {
+               __vb2_queue_free(q, allocated_buffers);
+               return ret;
+       }
+
+       /*
+        * Return the number of successfully allocated buffers
+        * to the userspace.
+        */
+       create->count = allocated_buffers;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_create_bufs);
+
 /**
  * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
  * @vb:                vb2_buffer to which the plane in question belongs to
@@ -662,7 +801,7 @@ EXPORT_SYMBOL_GPL(vb2_buffer_done);
  * __fill_vb2_buffer() - fill a vb2_buffer with information provided in
  * a v4l2_buffer by the userspace
  */
-static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
+static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
                                struct v4l2_plane *v4l2_planes)
 {
        unsigned int plane;
@@ -726,7 +865,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
 /**
  * __qbuf_userptr() - handle qbuf of a USERPTR buffer
  */
-static int __qbuf_userptr(struct vb2_buffer *vb, struct v4l2_buffer *b)
+static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 {
        struct v4l2_plane planes[VIDEO_MAX_PLANES];
        struct vb2_queue *q = vb->vb2_queue;
@@ -815,7 +954,7 @@ err:
 /**
  * __qbuf_mmap() - handle qbuf of an MMAP buffer
  */
-static int __qbuf_mmap(struct vb2_buffer *vb, struct v4l2_buffer *b)
+static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
 {
        return __fill_vb2_buffer(vb, b, vb->v4l2_planes);
 }
@@ -832,6 +971,95 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
        q->ops->buf_queue(vb);
 }
 
+static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
+{
+       struct vb2_queue *q = vb->vb2_queue;
+       int ret;
+
+       switch (q->memory) {
+       case V4L2_MEMORY_MMAP:
+               ret = __qbuf_mmap(vb, b);
+               break;
+       case V4L2_MEMORY_USERPTR:
+               ret = __qbuf_userptr(vb, b);
+               break;
+       default:
+               WARN(1, "Invalid queue type\n");
+               ret = -EINVAL;
+       }
+
+       if (!ret)
+               ret = call_qop(q, buf_prepare, vb);
+       if (ret)
+               dprintk(1, "qbuf: buffer preparation failed: %d\n", ret);
+       else
+               vb->state = VB2_BUF_STATE_PREPARED;
+
+       return ret;
+}
+
+/**
+ * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
+ * @q:         videobuf2 queue
+ * @b:         buffer structure passed from userspace to vidioc_prepare_buf
+ *             handler in driver
+ *
+ * Should be called from vidioc_prepare_buf ioctl handler of a driver.
+ * This function:
+ * 1) verifies the passed buffer,
+ * 2) calls buf_prepare callback in the driver (if provided), in which
+ *    driver-specific buffer initialization can be performed,
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_prepare_buf handler in driver.
+ */
+int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
+{
+       struct vb2_buffer *vb;
+       int ret;
+
+       if (q->fileio) {
+               dprintk(1, "%s(): file io in progress\n", __func__);
+               return -EBUSY;
+       }
+
+       if (b->type != q->type) {
+               dprintk(1, "%s(): invalid buffer type\n", __func__);
+               return -EINVAL;
+       }
+
+       if (b->index >= q->num_buffers) {
+               dprintk(1, "%s(): buffer index out of range\n", __func__);
+               return -EINVAL;
+       }
+
+       vb = q->bufs[b->index];
+       if (NULL == vb) {
+               /* Should never happen */
+               dprintk(1, "%s(): buffer is NULL\n", __func__);
+               return -EINVAL;
+       }
+
+       if (b->memory != q->memory) {
+               dprintk(1, "%s(): invalid memory type\n", __func__);
+               return -EINVAL;
+       }
+
+       if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+               dprintk(1, "%s(): invalid buffer state %d\n", __func__, vb->state);
+               return -EINVAL;
+       }
+
+       ret = __buf_prepare(vb, b);
+       if (ret < 0)
+               return ret;
+
+       __fill_v4l2_buffer(vb, b);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_prepare_buf);
+
 /**
  * vb2_qbuf() - Queue a buffer from userspace
  * @q:         videobuf2 queue
@@ -841,8 +1069,8 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
  * Should be called from vidioc_qbuf ioctl handler of a driver.
  * This function:
  * 1) verifies the passed buffer,
- * 2) calls buf_prepare callback in the driver (if provided), in which
- *    driver-specific buffer initialization can be performed,
+ * 2) if necessary, calls buf_prepare callback in the driver (if provided), in
+ *    which driver-specific buffer initialization can be performed,
  * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
  *    callback for processing.
  *
@@ -852,7 +1080,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
 {
        struct vb2_buffer *vb;
-       int ret = 0;
+       int ret;
 
        if (q->fileio) {
                dprintk(1, "qbuf: file io in progress\n");
@@ -881,29 +1109,18 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
                return -EINVAL;
        }
 
-       if (vb->state != VB2_BUF_STATE_DEQUEUED) {
+       switch (vb->state) {
+       case VB2_BUF_STATE_DEQUEUED:
+               ret = __buf_prepare(vb, b);
+               if (ret)
+                       return ret;
+       case VB2_BUF_STATE_PREPARED:
+               break;
+       default:
                dprintk(1, "qbuf: buffer already in use\n");
                return -EINVAL;
        }
 
-       if (q->memory == V4L2_MEMORY_MMAP)
-               ret = __qbuf_mmap(vb, b);
-       else if (q->memory == V4L2_MEMORY_USERPTR)
-               ret = __qbuf_userptr(vb, b);
-       else {
-               WARN(1, "Invalid queue type\n");
-               return -EINVAL;
-       }
-
-       if (ret)
-               return ret;
-
-       ret = call_qop(q, buf_prepare, vb);
-       if (ret) {
-               dprintk(1, "qbuf: buffer preparation failed\n");
-               return ret;
-       }
-
        /*
         * Add to the queued buffers list, a buffer will stay on it until
         * dequeued in dqbuf.
@@ -918,6 +1135,9 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
        if (q->streaming)
                __enqueue_in_driver(vb);
 
+       /* Fill buffer information for the userspace */
+       __fill_v4l2_buffer(vb, b);
+
        dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index);
        return 0;
 }
@@ -1347,6 +1567,37 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
 }
 EXPORT_SYMBOL_GPL(vb2_mmap);
 
+#ifndef CONFIG_MMU
+unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
+                                   unsigned long addr,
+                                   unsigned long len,
+                                   unsigned long pgoff,
+                                   unsigned long flags)
+{
+       unsigned long off = pgoff << PAGE_SHIFT;
+       struct vb2_buffer *vb;
+       unsigned int buffer, plane;
+       int ret;
+
+       if (q->memory != V4L2_MEMORY_MMAP) {
+               dprintk(1, "Queue is not currently set up for mmap\n");
+               return -EINVAL;
+       }
+
+       /*
+        * Find the plane corresponding to the offset passed by userspace.
+        */
+       ret = __find_plane_by_offset(q, off, &buffer, &plane);
+       if (ret)
+               return ret;
+
+       vb = q->bufs[buffer];
+
+       return (unsigned long)vb2_plane_vaddr(vb, plane);
+}
+EXPORT_SYMBOL_GPL(vb2_get_unmapped_area);
+#endif
+
 static int __vb2_init_fileio(struct vb2_queue *q, int read);
 static int __vb2_cleanup_fileio(struct vb2_queue *q);
 
@@ -1464,7 +1715,7 @@ void vb2_queue_release(struct vb2_queue *q)
 {
        __vb2_cleanup_fileio(q);
        __vb2_queue_cancel(q);
-       __vb2_queue_free(q);
+       __vb2_queue_free(q, q->num_buffers);
 }
 EXPORT_SYMBOL_GPL(vb2_queue_release);
 
index 7cf94c0..7d754fb 100644 (file)
@@ -650,9 +650,9 @@ static void vivi_stop_generating(struct vivi_dev *dev)
 /* ------------------------------------------------------------------
        Videobuf operations
    ------------------------------------------------------------------*/
-static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
-                               unsigned int *nplanes, unsigned int sizes[],
-                               void *alloc_ctxs[])
+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+                               unsigned int *nbuffers, unsigned int *nplanes,
+                               unsigned int sizes[], void *alloc_ctxs[])
 {
        struct vivi_dev *dev = vb2_get_drv_priv(vq);
        unsigned long size;
index ed5a6d3..cbd5d70 100644 (file)
@@ -310,18 +310,21 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l
                                 struct device_node *np)
 {
        struct resource res;
-       if (lookup) {
-               for(; lookup->name != NULL; lookup++) {
-                       if (!of_device_is_compatible(np, lookup->compatible))
-                               continue;
-                       if (of_address_to_resource(np, 0, &res))
-                               continue;
-                       if (res.start != lookup->phys_addr)
-                               continue;
-                       pr_debug("%s: devname=%s\n", np->full_name, lookup->name);
-                       return lookup;
-               }
+
+       if (!lookup)
+               return NULL;
+
+       for(; lookup->name != NULL; lookup++) {
+               if (!of_device_is_compatible(np, lookup->compatible))
+                       continue;
+               if (of_address_to_resource(np, 0, &res))
+                       continue;
+               if (res.start != lookup->phys_addr)
+                       continue;
+               pr_debug("%s: devname=%s\n", np->full_name, lookup->name);
+               return lookup;
        }
+
        return NULL;
 }
 
@@ -329,8 +332,9 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l
  * of_platform_bus_create() - Create a device for a node and its children.
  * @bus: device node of the bus to instantiate
  * @matches: match table for bus nodes
- * disallow recursive creation of child buses
+ * @lookup: auxdata table for matching id and platform_data with device nodes
  * @parent: parent for new device, or NULL for top level.
+ * @strict: require compatible property
  *
  * Creates a platform_device for the provided device_node, and optionally
  * recursively create devices for all the child nodes.
index d132c27..25cdff3 100644 (file)
@@ -30,12 +30,6 @@ source "drivers/staging/et131x/Kconfig"
 
 source "drivers/staging/slicoss/Kconfig"
 
-source "drivers/staging/go7007/Kconfig"
-
-source "drivers/staging/cx25821/Kconfig"
-
-source "drivers/staging/cxd2099/Kconfig"
-
 source "drivers/staging/usbip/Kconfig"
 
 source "drivers/staging/winbond/Kconfig"
@@ -104,20 +98,12 @@ source "drivers/staging/wlags49_h25/Kconfig"
 
 source "drivers/staging/sm7xx/Kconfig"
 
-source "drivers/staging/dt3155v4l/Kconfig"
-
 source "drivers/staging/crystalhd/Kconfig"
 
 source "drivers/staging/cxt1e1/Kconfig"
 
 source "drivers/staging/xgifb/Kconfig"
 
-source "drivers/staging/lirc/Kconfig"
-
-source "drivers/staging/easycap/Kconfig"
-
-source "drivers/staging/solo6x10/Kconfig"
-
 source "drivers/staging/tidspbridge/Kconfig"
 
 source "drivers/staging/quickstart/Kconfig"
@@ -144,4 +130,6 @@ source "drivers/staging/mei/Kconfig"
 
 source "drivers/staging/nvec/Kconfig"
 
+source "drivers/staging/media/Kconfig"
+
 endif # STAGING
index 936b7c2..a25f3f2 100644 (file)
@@ -4,12 +4,9 @@
 obj-$(CONFIG_STAGING)          += staging.o
 
 obj-y                          += serial/
+obj-y                          += media/
 obj-$(CONFIG_ET131X)           += et131x/
 obj-$(CONFIG_SLICOSS)          += slicoss/
-obj-$(CONFIG_VIDEO_GO7007)     += go7007/
-obj-$(CONFIG_VIDEO_CX25821)    += cx25821/
-obj-$(CONFIG_DVB_CXD2099)      += cxd2099/
-obj-$(CONFIG_LIRC_STAGING)     += lirc/
 obj-$(CONFIG_USBIP_CORE)       += usbip/
 obj-$(CONFIG_W35UND)           += winbond/
 obj-$(CONFIG_PRISM2_USB)       += wlan-ng/
@@ -44,12 +41,9 @@ obj-$(CONFIG_ZCACHE)         += zcache/
 obj-$(CONFIG_WLAGS49_H2)       += wlags49_h2/
 obj-$(CONFIG_WLAGS49_H25)      += wlags49_h25/
 obj-$(CONFIG_FB_SM7XX)         += sm7xx/
-obj-$(CONFIG_VIDEO_DT3155)     += dt3155v4l/
 obj-$(CONFIG_CRYSTALHD)                += crystalhd/
 obj-$(CONFIG_CXT1E1)           += cxt1e1/
 obj-$(CONFIG_FB_XGI)           += xgifb/
-obj-$(CONFIG_EASYCAP)          += easycap/
-obj-$(CONFIG_SOLO6X10)         += solo6x10/
 obj-$(CONFIG_TIDSPBRIDGE)      += tidspbridge/
 obj-$(CONFIG_ACPI_QUICKSTART)  += quickstart/
 obj-$(CONFIG_SBE_2T3E3)                += sbe-2t3e3/
diff --git a/drivers/staging/cx25821/README b/drivers/staging/cx25821/README
deleted file mode 100644 (file)
index a9ba50b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-Todo:
-       - checkpatch.pl cleanups
-       - sparse cleanups
-
-Please send patches to linux-media@vger.kernel.org
-
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
new file mode 100644 (file)
index 0000000..7e5caa3
--- /dev/null
@@ -0,0 +1,37 @@
+menuconfig STAGING_MEDIA
+        bool "Media staging drivers"
+        default n
+        ---help---
+          This option allows you to select a number of media drivers that
+         don't have the "normal" Linux kernel quality level.
+         Most of them don't follow properly the V4L, DVB and/or RC API's,
+         so, they won't likely work fine with the existing applications.
+         That also means that, one fixed, their API's will change to match
+         the existing ones.
+
+          If you wish to work on these drivers, to help improve them, or
+          to report problems you have with them, please use the
+         linux-media@vger.kernel.org mailing list.
+
+          If in doubt, say N here.
+
+
+if STAGING_MEDIA
+
+# Please keep them in alphabetic order
+source "drivers/staging/media/as102/Kconfig"
+
+source "drivers/staging/media/cxd2099/Kconfig"
+
+source "drivers/staging/media/dt3155v4l/Kconfig"
+
+source "drivers/staging/media/easycap/Kconfig"
+
+source "drivers/staging/media/go7007/Kconfig"
+
+source "drivers/staging/media/solo6x10/Kconfig"
+
+# Keep LIRC at the end, as it has sub-menus
+source "drivers/staging/media/lirc/Kconfig"
+
+endif
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
new file mode 100644 (file)
index 0000000..c69124c
--- /dev/null
@@ -0,0 +1,7 @@
+obj-$(CONFIG_DVB_AS102)                += as102/
+obj-$(CONFIG_DVB_CXD2099)      += cxd2099/
+obj-$(CONFIG_EASYCAP)          += easycap/
+obj-$(CONFIG_LIRC_STAGING)     += lirc/
+obj-$(CONFIG_SOLO6X10)         += solo6x10/
+obj-$(CONFIG_VIDEO_DT3155)     += dt3155v4l/
+obj-$(CONFIG_VIDEO_GO7007)     += go7007/
diff --git a/drivers/staging/media/as102/Kconfig b/drivers/staging/media/as102/Kconfig
new file mode 100644 (file)
index 0000000..5865029
--- /dev/null
@@ -0,0 +1,7 @@
+config DVB_AS102
+       tristate "Abilis AS102 DVB receiver"
+       depends on DVB_CORE && USB && I2C && INPUT
+       help
+         Choose Y or M here if you have a device containing an AS102
+
+         To compile this driver as a module, choose M here
diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile
new file mode 100644 (file)
index 0000000..e7dbb6f
--- /dev/null
@@ -0,0 +1,6 @@
+dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \
+               as102_fe.o as102_usb_drv.o as10x_cmd_cfg.o
+
+obj-$(CONFIG_DVB_AS102) += dvb-as102.o
+
+EXTRA_CFLAGS += -DCONFIG_AS102_USB -Idrivers/media/dvb/dvb-core
diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c
new file mode 100644 (file)
index 0000000..d335c7d
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/kref.h>
+#include <asm/uaccess.h>
+#include <linux/usb.h>
+
+/* header file for Usb device driver*/
+#include "as102_drv.h"
+#include "as102_fw.h"
+#include "dvbdev.h"
+
+int debug;
+module_param_named(debug, debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)");
+
+int dual_tuner;
+module_param_named(dual_tuner, dual_tuner, int, 0644);
+MODULE_PARM_DESC(dual_tuner, "Activate Dual-Tuner config (default: off)");
+
+static int fw_upload = 1;
+module_param_named(fw_upload, fw_upload, int, 0644);
+MODULE_PARM_DESC(fw_upload, "Turn on/off default FW upload (default: on)");
+
+static int pid_filtering;
+module_param_named(pid_filtering, pid_filtering, int, 0644);
+MODULE_PARM_DESC(pid_filtering, "Activate HW PID filtering (default: off)");
+
+static int ts_auto_disable;
+module_param_named(ts_auto_disable, ts_auto_disable, int, 0644);
+MODULE_PARM_DESC(ts_auto_disable, "Stream Auto Enable on FW (default: off)");
+
+int elna_enable = 1;
+module_param_named(elna_enable, elna_enable, int, 0644);
+MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)");
+
+#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+#endif
+
+static void as102_stop_stream(struct as102_dev_t *dev)
+{
+       struct as102_bus_adapter_t *bus_adap;
+
+       if (dev != NULL)
+               bus_adap = &dev->bus_adap;
+       else
+               return;
+
+       if (bus_adap->ops->stop_stream != NULL)
+               bus_adap->ops->stop_stream(dev);
+
+       if (ts_auto_disable) {
+               if (mutex_lock_interruptible(&dev->bus_adap.lock))
+                       return;
+
+               if (as10x_cmd_stop_streaming(bus_adap) < 0)
+                       dprintk(debug, "as10x_cmd_stop_streaming failed\n");
+
+               mutex_unlock(&dev->bus_adap.lock);
+       }
+}
+
+static int as102_start_stream(struct as102_dev_t *dev)
+{
+       struct as102_bus_adapter_t *bus_adap;
+       int ret = -EFAULT;
+
+       if (dev != NULL)
+               bus_adap = &dev->bus_adap;
+       else
+               return ret;
+
+       if (bus_adap->ops->start_stream != NULL)
+               ret = bus_adap->ops->start_stream(dev);
+
+       if (ts_auto_disable) {
+               if (mutex_lock_interruptible(&dev->bus_adap.lock))
+                       return -EFAULT;
+
+               ret = as10x_cmd_start_streaming(bus_adap);
+
+               mutex_unlock(&dev->bus_adap.lock);
+       }
+
+       return ret;
+}
+
+static int as10x_pid_filter(struct as102_dev_t *dev,
+                           int index, u16 pid, int onoff) {
+
+       struct as102_bus_adapter_t *bus_adap = &dev->bus_adap;
+       int ret = -EFAULT;
+
+       ENTER();
+
+       if (mutex_lock_interruptible(&dev->bus_adap.lock)) {
+               dprintk(debug, "mutex_lock_interruptible(lock) failed !\n");
+               return -EBUSY;
+       }
+
+       switch (onoff) {
+       case 0:
+           ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid);
+           dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n",
+                   index, pid, ret);
+           break;
+       case 1:
+       {
+           struct as10x_ts_filter filter;
+
+           filter.type = TS_PID_TYPE_TS;
+           filter.idx = 0xFF;
+           filter.pid = pid;
+
+           ret = as10x_cmd_add_PID_filter(bus_adap, &filter);
+           dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n",
+                   index, filter.idx, filter.pid, ret);
+           break;
+       }
+       }
+
+       mutex_unlock(&dev->bus_adap.lock);
+
+       LEAVE();
+       return ret;
+}
+
+static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       int ret = 0;
+       struct dvb_demux *demux = dvbdmxfeed->demux;
+       struct as102_dev_t *as102_dev = demux->priv;
+
+       ENTER();
+
+       if (mutex_lock_interruptible(&as102_dev->sem))
+               return -ERESTARTSYS;
+
+       if (pid_filtering) {
+               as10x_pid_filter(as102_dev,
+                               dvbdmxfeed->index, dvbdmxfeed->pid, 1);
+       }
+
+       if (as102_dev->streaming++ == 0)
+               ret = as102_start_stream(as102_dev);
+
+       mutex_unlock(&as102_dev->sem);
+       LEAVE();
+       return ret;
+}
+
+static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+       struct dvb_demux *demux = dvbdmxfeed->demux;
+       struct as102_dev_t *as102_dev = demux->priv;
+
+       ENTER();
+
+       if (mutex_lock_interruptible(&as102_dev->sem))
+               return -ERESTARTSYS;
+
+       if (--as102_dev->streaming == 0)
+               as102_stop_stream(as102_dev);
+
+       if (pid_filtering) {
+               as10x_pid_filter(as102_dev,
+                               dvbdmxfeed->index, dvbdmxfeed->pid, 0);
+       }
+
+       mutex_unlock(&as102_dev->sem);
+       LEAVE();
+       return 0;
+}
+
+int as102_dvb_register(struct as102_dev_t *as102_dev)
+{
+       int ret = 0;
+       ENTER();
+
+       ret = dvb_register_adapter(&as102_dev->dvb_adap,
+                                  as102_dev->name,
+                                  THIS_MODULE,
+#if defined(CONFIG_AS102_USB)
+                                  &as102_dev->bus_adap.usb_dev->dev
+#elif defined(CONFIG_AS102_SPI)
+                                  &as102_dev->bus_adap.spi_dev->dev
+#else
+#error >>> dvb_register_adapter <<<
+#endif
+#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR
+                                  , adapter_nr
+#endif
+                                  );
+       if (ret < 0) {
+               err("%s: dvb_register_adapter() failed (errno = %d)",
+                   __func__, ret);
+               goto failed;
+       }
+
+       as102_dev->dvb_dmx.priv = as102_dev;
+       as102_dev->dvb_dmx.filternum = pid_filtering ? 16 : 256;
+       as102_dev->dvb_dmx.feednum = 256;
+       as102_dev->dvb_dmx.start_feed = as102_dvb_dmx_start_feed;
+       as102_dev->dvb_dmx.stop_feed = as102_dvb_dmx_stop_feed;
+
+       as102_dev->dvb_dmx.dmx.capabilities = DMX_TS_FILTERING |
+                                             DMX_SECTION_FILTERING;
+
+       as102_dev->dvb_dmxdev.filternum = as102_dev->dvb_dmx.filternum;
+       as102_dev->dvb_dmxdev.demux = &as102_dev->dvb_dmx.dmx;
+       as102_dev->dvb_dmxdev.capabilities = 0;
+
+       ret = dvb_dmx_init(&as102_dev->dvb_dmx);
+       if (ret < 0) {
+               err("%s: dvb_dmx_init() failed (errno = %d)", __func__, ret);
+               goto failed;
+       }
+
+       ret = dvb_dmxdev_init(&as102_dev->dvb_dmxdev, &as102_dev->dvb_adap);
+       if (ret < 0) {
+               err("%s: dvb_dmxdev_init() failed (errno = %d)", __func__,
+                   ret);
+               goto failed;
+       }
+
+       ret = as102_dvb_register_fe(as102_dev, &as102_dev->dvb_fe);
+       if (ret < 0) {
+               err("%s: as102_dvb_register_frontend() failed (errno = %d)",
+                   __func__, ret);
+               goto failed;
+       }
+
+       /* init bus mutex for token locking */
+       mutex_init(&as102_dev->bus_adap.lock);
+
+       /* init start / stop stream mutex */
+       mutex_init(&as102_dev->sem);
+
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+       /*
+        * try to load as102 firmware. If firmware upload failed, we'll be
+        * able to upload it later.
+        */
+       if (fw_upload)
+               try_then_request_module(as102_fw_upload(&as102_dev->bus_adap),
+                               "firmware_class");
+#endif
+
+failed:
+       LEAVE();
+       /* FIXME: free dvb_XXX */
+       return ret;
+}
+
+void as102_dvb_unregister(struct as102_dev_t *as102_dev)
+{
+       ENTER();
+
+       /* unregister as102 frontend */
+       as102_dvb_unregister_fe(&as102_dev->dvb_fe);
+
+       /* unregister demux device */
+       dvb_dmxdev_release(&as102_dev->dvb_dmxdev);
+       dvb_dmx_release(&as102_dev->dvb_dmx);
+
+       /* unregister dvb adapter */
+       dvb_unregister_adapter(&as102_dev->dvb_adap);
+
+       LEAVE();
+}
+
+static int __init as102_driver_init(void)
+{
+       int ret = 0;
+
+       ENTER();
+
+       /* register this driver with the low level subsystem */
+#if defined(CONFIG_AS102_USB)
+       ret = usb_register(&as102_usb_driver);
+       if (ret)
+               err("usb_register failed (ret = %d)", ret);
+#endif
+#if defined(CONFIG_AS102_SPI)
+       ret = spi_register_driver(&as102_spi_driver);
+       if (ret)
+               printk(KERN_ERR "spi_register failed (ret = %d)", ret);
+#endif
+
+       LEAVE();
+       return ret;
+}
+
+/*
+ * Mandatory function : Adds a special section to the module indicating
+ * where initialisation function is defined
+ */
+module_init(as102_driver_init);
+
+/**
+ * as102_driver_exit - as102 driver exit point
+ *
+ * This function is called when device has to be removed.
+ */
+static void __exit as102_driver_exit(void)
+{
+       ENTER();
+       /* deregister this driver with the low level bus subsystem */
+#if defined(CONFIG_AS102_USB)
+       usb_deregister(&as102_usb_driver);
+#endif
+#if defined(CONFIG_AS102_SPI)
+       spi_unregister_driver(&as102_spi_driver);
+#endif
+       LEAVE();
+}
+
+/*
+ * required function for unload: Adds a special section to the module
+ * indicating where unload function is defined
+ */
+module_exit(as102_driver_exit);
+/* modinfo details */
+MODULE_DESCRIPTION(DRIVER_FULL_NAME);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>");
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h
new file mode 100644 (file)
index 0000000..bcda635
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(CONFIG_AS102_USB)
+#include <linux/usb.h>
+extern struct usb_driver as102_usb_driver;
+#endif
+
+#if defined(CONFIG_AS102_SPI)
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/cdev.h>
+
+extern struct spi_driver as102_spi_driver;
+#endif
+
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dmxdev.h"
+
+#define DRIVER_FULL_NAME "Abilis Systems as10x usb driver"
+#define DRIVER_NAME "as10x_usb"
+
+extern int debug;
+
+#define dprintk(debug, args...) \
+       do { if (debug) {       \
+               printk(KERN_DEBUG "%s: ",__FUNCTION__); \
+               printk(args);   \
+       } } while (0)
+
+#ifdef TRACE
+#define ENTER()                 printk(">> enter %s\n", __FUNCTION__)
+#define LEAVE()                 printk("<< leave %s\n", __FUNCTION__)
+#else
+#define ENTER()
+#define LEAVE()
+#endif
+
+#define AS102_DEVICE_MAJOR     192
+
+#define AS102_USB_BUF_SIZE     512
+#define MAX_STREAM_URB         32
+
+#include "as10x_cmd.h"
+
+#if defined(CONFIG_AS102_USB)
+#include "as102_usb_drv.h"
+#endif
+
+#if defined(CONFIG_AS102_SPI)
+#include "as10x_spi_drv.h"
+#endif
+
+
+struct as102_bus_adapter_t {
+#if defined(CONFIG_AS102_USB)
+       struct usb_device *usb_dev;
+#elif defined(CONFIG_AS102_SPI)
+       struct spi_device *spi_dev;
+       struct cdev cdev; /* spidev raw device */
+
+       struct timer_list timer;
+       struct completion xfer_done;
+#endif
+       /* bus token lock */
+       struct mutex lock;
+       /* low level interface for bus adapter */
+       union as10x_bus_token_t {
+#if defined(CONFIG_AS102_USB)
+               /* usb token */
+               struct as10x_usb_token_cmd_t usb;
+#endif
+#if defined(CONFIG_AS102_SPI)
+               /* spi token */
+               struct as10x_spi_token_cmd_t spi;
+#endif
+       } token;
+
+       /* token cmd xfer id */
+       uint16_t cmd_xid;
+
+       /* as10x command and response for dvb interface*/
+       struct as10x_cmd_t *cmd, *rsp;
+
+       /* bus adapter private ops callback */
+       struct as102_priv_ops_t *ops;
+};
+
+struct as102_dev_t {
+       const char *name;
+       struct as102_bus_adapter_t bus_adap;
+       struct list_head device_entry;
+       struct kref kref;
+       unsigned long minor;
+
+       struct dvb_adapter dvb_adap;
+       struct dvb_frontend dvb_fe;
+       struct dvb_demux dvb_dmx;
+       struct dmxdev dvb_dmxdev;
+
+       /* demodulator stats */
+       struct as10x_demod_stats demod_stats;
+       /* signal strength */
+       uint16_t signal_strength;
+       /* bit error rate */
+       uint32_t ber;
+
+       /* timer handle to trig ts stream download */
+       struct timer_list timer_handle;
+
+       struct mutex sem;
+       dma_addr_t dma_addr;
+       void *stream;
+       int streaming;
+       struct urb *stream_urb[MAX_STREAM_URB];
+};
+
+int as102_dvb_register(struct as102_dev_t *dev);
+void as102_dvb_unregister(struct as102_dev_t *dev);
+
+int as102_dvb_register_fe(struct as102_dev_t *dev, struct dvb_frontend *fe);
+int as102_dvb_unregister_fe(struct dvb_frontend *dev);
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c
new file mode 100644 (file)
index 0000000..3550f90
--- /dev/null
@@ -0,0 +1,603 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/version.h>
+
+#include "as102_drv.h"
+#include "as10x_types.h"
+#include "as10x_cmd.h"
+
+extern int elna_enable;
+
+static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst,
+                                        struct as10x_tps *src);
+
+static void as102_fe_copy_tune_parameters(struct as10x_tune_args *dst,
+                                         struct dvb_frontend_parameters *src);
+
+static int as102_fe_set_frontend(struct dvb_frontend *fe,
+                                struct dvb_frontend_parameters *params)
+{
+       int ret = 0;
+       struct as102_dev_t *dev;
+       struct as10x_tune_args tune_args = { 0 };
+
+       ENTER();
+
+       dev = (struct as102_dev_t *) fe->tuner_priv;
+       if (dev == NULL)
+               return -ENODEV;
+
+       if (mutex_lock_interruptible(&dev->bus_adap.lock))
+               return -EBUSY;
+
+       as102_fe_copy_tune_parameters(&tune_args, params);
+
+       /* send abilis command: SET_TUNE */
+       ret =  as10x_cmd_set_tune(&dev->bus_adap, &tune_args);
+       if (ret != 0)
+               dprintk(debug, "as10x_cmd_set_tune failed. (err = %d)\n", ret);
+
+       mutex_unlock(&dev->bus_adap.lock);
+
+       LEAVE();
+       return (ret < 0) ? -EINVAL : 0;
+}
+
+static int as102_fe_get_frontend(struct dvb_frontend *fe,
+                                struct dvb_frontend_parameters *p) {
+       int ret = 0;
+       struct as102_dev_t *dev;
+       struct as10x_tps tps = { 0 };
+
+       ENTER();
+
+       dev = (struct as102_dev_t *) fe->tuner_priv;
+       if (dev == NULL)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&dev->bus_adap.lock))
+               return -EBUSY;
+
+       /* send abilis command: GET_TPS */
+       ret = as10x_cmd_get_tps(&dev->bus_adap, &tps);
+
+       if (ret == 0)
+               as10x_fe_copy_tps_parameters(p, &tps);
+
+       mutex_unlock(&dev->bus_adap.lock);
+
+       LEAVE();
+       return (ret < 0) ? -EINVAL : 0;
+}
+
+static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
+                       struct dvb_frontend_tune_settings *settings) {
+       ENTER();
+
+#if 0
+       dprintk(debug, "step_size    = %d\n", settings->step_size);
+       dprintk(debug, "max_drift    = %d\n", settings->max_drift);
+       dprintk(debug, "min_delay_ms = %d -> %d\n", settings->min_delay_ms,
+               1000);
+#endif
+
+       settings->min_delay_ms = 1000;
+
+       LEAVE();
+       return 0;
+}
+
+
+static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+       int ret = 0;
+       struct as102_dev_t *dev;
+       struct as10x_tune_status tstate = { 0 };
+
+       ENTER();
+
+       dev = (struct as102_dev_t *) fe->tuner_priv;
+       if (dev == NULL)
+               return -ENODEV;
+
+       if (mutex_lock_interruptible(&dev->bus_adap.lock))
+               return -EBUSY;
+
+       /* send abilis command: GET_TUNE_STATUS */
+       ret = as10x_cmd_get_tune_status(&dev->bus_adap, &tstate);
+       if (ret < 0) {
+               dprintk(debug, "as10x_cmd_get_tune_status failed (err = %d)\n",
+                       ret);
+               goto out;
+       }
+
+       dev->signal_strength  = tstate.signal_strength;
+       dev->ber  = tstate.BER;
+
+       switch (tstate.tune_state) {
+       case TUNE_STATUS_SIGNAL_DVB_OK:
+               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+               break;
+       case TUNE_STATUS_STREAM_DETECTED:
+               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC;
+               break;
+       case TUNE_STATUS_STREAM_TUNED:
+               *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
+                       FE_HAS_LOCK;
+               break;
+       default:
+               *status = TUNE_STATUS_NOT_TUNED;
+       }
+
+       dprintk(debug, "tuner status: 0x%02x, strength %d, per: %d, ber: %d\n",
+                       tstate.tune_state, tstate.signal_strength,
+                       tstate.PER, tstate.BER);
+
+       if (*status & FE_HAS_LOCK) {
+               if (as10x_cmd_get_demod_stats(&dev->bus_adap,
+                       (struct as10x_demod_stats *) &dev->demod_stats) < 0) {
+                       memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
+                       dprintk(debug, "as10x_cmd_get_demod_stats failed "
+                               "(probably not tuned)\n");
+               } else {
+                       dprintk(debug,
+                               "demod status: fc: 0x%08x, bad fc: 0x%08x, "
+                               "bytes corrected: 0x%08x , MER: 0x%04x\n",
+                               dev->demod_stats.frame_count,
+                               dev->demod_stats.bad_frame_count,
+                               dev->demod_stats.bytes_fixed_by_rs,
+                               dev->demod_stats.mer);
+               }
+       } else {
+               memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
+       }
+
+out:
+       mutex_unlock(&dev->bus_adap.lock);
+       LEAVE();
+       return ret;
+}
+
+/*
+ * Note:
+ * - in AS102 SNR=MER
+ *   - the SNR will be returned in linear terms, i.e. not in dB
+ *   - the accuracy equals Â±2dB for a SNR range from 4dB to 30dB
+ *   - the accuracy is >2dB for SNR values outside this range
+ */
+static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+       struct as102_dev_t *dev;
+
+       ENTER();
+
+       dev = (struct as102_dev_t *) fe->tuner_priv;
+       if (dev == NULL)
+               return -ENODEV;
+
+       *snr = dev->demod_stats.mer;
+
+       LEAVE();
+       return 0;
+}
+
+static int as102_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+       struct as102_dev_t *dev;
+
+       ENTER();
+
+       dev = (struct as102_dev_t *) fe->tuner_priv;
+       if (dev == NULL)
+               return -ENODEV;
+
+       *ber = dev->ber;
+
+       LEAVE();
+       return 0;
+}
+
+static int as102_fe_read_signal_strength(struct dvb_frontend *fe,
+                                        u16 *strength)
+{
+       struct as102_dev_t *dev;
+
+       ENTER();
+
+       dev = (struct as102_dev_t *) fe->tuner_priv;
+       if (dev == NULL)
+               return -ENODEV;
+
+       *strength = (((0xffff * 400) * dev->signal_strength + 41000) * 2);
+
+       LEAVE();
+       return 0;
+}
+
+static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+       struct as102_dev_t *dev;
+
+       ENTER();
+
+       dev = (struct as102_dev_t *) fe->tuner_priv;
+       if (dev == NULL)
+               return -ENODEV;
+
+       if (dev->demod_stats.has_started)
+               *ucblocks = dev->demod_stats.bad_frame_count;
+       else
+               *ucblocks = 0;
+
+       LEAVE();
+       return 0;
+}
+
+static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+       struct as102_dev_t *dev;
+       int ret;
+
+       ENTER();
+
+       dev = (struct as102_dev_t *) fe->tuner_priv;
+       if (dev == NULL)
+               return -ENODEV;
+
+       if (mutex_lock_interruptible(&dev->bus_adap.lock))
+               return -EBUSY;
+
+       if (acquire) {
+               if (elna_enable)
+                       as10x_cmd_set_context(&dev->bus_adap, 1010, 0xC0);
+
+               ret = as10x_cmd_turn_on(&dev->bus_adap);
+       } else {
+               ret = as10x_cmd_turn_off(&dev->bus_adap);
+       }
+
+       mutex_unlock(&dev->bus_adap.lock);
+
+       LEAVE();
+       return ret;
+}
+
+static struct dvb_frontend_ops as102_fe_ops = {
+       .info = {
+               .name                   = "Unknown AS102 device",
+               .type                   = FE_OFDM,
+               .frequency_min          = 174000000,
+               .frequency_max          = 862000000,
+               .frequency_stepsize     = 166667,
+               .caps = FE_CAN_INVERSION_AUTO
+                       | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
+                       | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO
+                       | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK
+                       | FE_CAN_QAM_AUTO
+                       | FE_CAN_TRANSMISSION_MODE_AUTO
+                       | FE_CAN_GUARD_INTERVAL_AUTO
+                       | FE_CAN_HIERARCHY_AUTO
+                       | FE_CAN_RECOVER
+                       | FE_CAN_MUTE_TS
+       },
+
+       .set_frontend           = as102_fe_set_frontend,
+       .get_frontend           = as102_fe_get_frontend,
+       .get_tune_settings      = as102_fe_get_tune_settings,
+
+       .read_status            = as102_fe_read_status,
+       .read_snr               = as102_fe_read_snr,
+       .read_ber               = as102_fe_read_ber,
+       .read_signal_strength   = as102_fe_read_signal_strength,
+       .read_ucblocks          = as102_fe_read_ucblocks,
+       .ts_bus_ctrl            = as102_fe_ts_bus_ctrl,
+};
+
+int as102_dvb_unregister_fe(struct dvb_frontend *fe)
+{
+       /* unregister frontend */
+       dvb_unregister_frontend(fe);
+
+       /* detach frontend */
+       dvb_frontend_detach(fe);
+
+       return 0;
+}
+
+int as102_dvb_register_fe(struct as102_dev_t *as102_dev,
+                         struct dvb_frontend *dvb_fe)
+{
+       int errno;
+       struct dvb_adapter *dvb_adap;
+
+       if (as102_dev == NULL)
+               return -EINVAL;
+
+       /* extract dvb_adapter */
+       dvb_adap = &as102_dev->dvb_adap;
+
+       /* init frontend callback ops */
+       memcpy(&dvb_fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops));
+       strncpy(dvb_fe->ops.info.name, as102_dev->name,
+               sizeof(dvb_fe->ops.info.name));
+
+       /* register dbvb frontend */
+       errno = dvb_register_frontend(dvb_adap, dvb_fe);
+       if (errno == 0)
+               dvb_fe->tuner_priv = as102_dev;
+
+       return errno;
+}
+
+static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst,
+                                        struct as10x_tps *as10x_tps)
+{
+
+       struct dvb_ofdm_parameters *fe_tps = &dst->u.ofdm;
+
+       /* extract consteallation */
+       switch (as10x_tps->constellation) {
+       case CONST_QPSK:
+               fe_tps->constellation = QPSK;
+               break;
+       case CONST_QAM16:
+               fe_tps->constellation = QAM_16;
+               break;
+       case CONST_QAM64:
+               fe_tps->constellation = QAM_64;
+               break;
+       }
+
+       /* extract hierarchy */
+       switch (as10x_tps->hierarchy) {
+       case HIER_NONE:
+               fe_tps->hierarchy_information = HIERARCHY_NONE;
+               break;
+       case HIER_ALPHA_1:
+               fe_tps->hierarchy_information = HIERARCHY_1;
+               break;
+       case HIER_ALPHA_2:
+               fe_tps->hierarchy_information = HIERARCHY_2;
+               break;
+       case HIER_ALPHA_4:
+               fe_tps->hierarchy_information = HIERARCHY_4;
+               break;
+       }
+
+       /* extract code rate HP */
+       switch (as10x_tps->code_rate_HP) {
+       case CODE_RATE_1_2:
+               fe_tps->code_rate_HP = FEC_1_2;
+               break;
+       case CODE_RATE_2_3:
+               fe_tps->code_rate_HP = FEC_2_3;
+               break;
+       case CODE_RATE_3_4:
+               fe_tps->code_rate_HP = FEC_3_4;
+               break;
+       case CODE_RATE_5_6:
+               fe_tps->code_rate_HP = FEC_5_6;
+               break;
+       case CODE_RATE_7_8:
+               fe_tps->code_rate_HP = FEC_7_8;
+               break;
+       }
+
+       /* extract code rate LP */
+       switch (as10x_tps->code_rate_LP) {
+       case CODE_RATE_1_2:
+               fe_tps->code_rate_LP = FEC_1_2;
+               break;
+       case CODE_RATE_2_3:
+               fe_tps->code_rate_LP = FEC_2_3;
+               break;
+       case CODE_RATE_3_4:
+               fe_tps->code_rate_LP = FEC_3_4;
+               break;
+       case CODE_RATE_5_6:
+               fe_tps->code_rate_LP = FEC_5_6;
+               break;
+       case CODE_RATE_7_8:
+               fe_tps->code_rate_LP = FEC_7_8;
+               break;
+       }
+
+       /* extract guard interval */
+       switch (as10x_tps->guard_interval) {
+       case GUARD_INT_1_32:
+               fe_tps->guard_interval = GUARD_INTERVAL_1_32;
+               break;
+       case GUARD_INT_1_16:
+               fe_tps->guard_interval = GUARD_INTERVAL_1_16;
+               break;
+       case GUARD_INT_1_8:
+               fe_tps->guard_interval = GUARD_INTERVAL_1_8;
+               break;
+       case GUARD_INT_1_4:
+               fe_tps->guard_interval = GUARD_INTERVAL_1_4;
+               break;
+       }
+
+       /* extract transmission mode */
+       switch (as10x_tps->transmission_mode) {
+       case TRANS_MODE_2K:
+               fe_tps->transmission_mode = TRANSMISSION_MODE_2K;
+               break;
+       case TRANS_MODE_8K:
+               fe_tps->transmission_mode = TRANSMISSION_MODE_8K;
+               break;
+       }
+}
+
+static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg)
+{
+       uint8_t c;
+
+       switch (arg) {
+       case FEC_1_2:
+               c = CODE_RATE_1_2;
+               break;
+       case FEC_2_3:
+               c = CODE_RATE_2_3;
+               break;
+       case FEC_3_4:
+               c = CODE_RATE_3_4;
+               break;
+       case FEC_5_6:
+               c = CODE_RATE_5_6;
+               break;
+       case FEC_7_8:
+               c = CODE_RATE_7_8;
+               break;
+       default:
+               c = CODE_RATE_UNKNOWN;
+               break;
+       }
+
+       return c;
+}
+
+static void as102_fe_copy_tune_parameters(struct as10x_tune_args *tune_args,
+                         struct dvb_frontend_parameters *params)
+{
+
+       /* set frequency */
+       tune_args->freq = params->frequency / 1000;
+
+       /* fix interleaving_mode */
+       tune_args->interleaving_mode = INTLV_NATIVE;
+
+       switch (params->u.ofdm.bandwidth) {
+       case BANDWIDTH_8_MHZ:
+               tune_args->bandwidth = BW_8_MHZ;
+               break;
+       case BANDWIDTH_7_MHZ:
+               tune_args->bandwidth = BW_7_MHZ;
+               break;
+       case BANDWIDTH_6_MHZ:
+               tune_args->bandwidth = BW_6_MHZ;
+               break;
+       default:
+               tune_args->bandwidth = BW_8_MHZ;
+       }
+
+       switch (params->u.ofdm.guard_interval) {
+       case GUARD_INTERVAL_1_32:
+               tune_args->guard_interval = GUARD_INT_1_32;
+               break;
+       case GUARD_INTERVAL_1_16:
+               tune_args->guard_interval = GUARD_INT_1_16;
+               break;
+       case GUARD_INTERVAL_1_8:
+               tune_args->guard_interval = GUARD_INT_1_8;
+               break;
+       case GUARD_INTERVAL_1_4:
+               tune_args->guard_interval = GUARD_INT_1_4;
+               break;
+       case GUARD_INTERVAL_AUTO:
+       default:
+               tune_args->guard_interval = GUARD_UNKNOWN;
+               break;
+       }
+
+       switch (params->u.ofdm.constellation) {
+       case QPSK:
+               tune_args->constellation = CONST_QPSK;
+               break;
+       case QAM_16:
+               tune_args->constellation = CONST_QAM16;
+               break;
+       case QAM_64:
+               tune_args->constellation = CONST_QAM64;
+               break;
+       default:
+               tune_args->constellation = CONST_UNKNOWN;
+               break;
+       }
+
+       switch (params->u.ofdm.transmission_mode) {
+       case TRANSMISSION_MODE_2K:
+               tune_args->transmission_mode = TRANS_MODE_2K;
+               break;
+       case TRANSMISSION_MODE_8K:
+               tune_args->transmission_mode = TRANS_MODE_8K;
+               break;
+       default:
+               tune_args->transmission_mode = TRANS_MODE_UNKNOWN;
+       }
+
+       switch (params->u.ofdm.hierarchy_information) {
+       case HIERARCHY_NONE:
+               tune_args->hierarchy = HIER_NONE;
+               break;
+       case HIERARCHY_1:
+               tune_args->hierarchy = HIER_ALPHA_1;
+               break;
+       case HIERARCHY_2:
+               tune_args->hierarchy = HIER_ALPHA_2;
+               break;
+       case HIERARCHY_4:
+               tune_args->hierarchy = HIER_ALPHA_4;
+               break;
+       case HIERARCHY_AUTO:
+               tune_args->hierarchy = HIER_UNKNOWN;
+               break;
+       }
+
+       dprintk(debug, "tuner parameters: freq: %d  bw: 0x%02x  gi: 0x%02x\n",
+                       params->frequency,
+                       tune_args->bandwidth,
+                       tune_args->guard_interval);
+
+       /*
+        * Detect a hierarchy selection
+        * if HP/LP are both set to FEC_NONE, HP will be selected.
+        */
+       if ((tune_args->hierarchy != HIER_NONE) &&
+                      ((params->u.ofdm.code_rate_LP == FEC_NONE) ||
+                       (params->u.ofdm.code_rate_HP == FEC_NONE))) {
+
+               if (params->u.ofdm.code_rate_LP == FEC_NONE) {
+                       tune_args->hier_select = HIER_HIGH_PRIORITY;
+                       tune_args->code_rate =
+                          as102_fe_get_code_rate(params->u.ofdm.code_rate_HP);
+               }
+
+               if (params->u.ofdm.code_rate_HP == FEC_NONE) {
+                       tune_args->hier_select = HIER_LOW_PRIORITY;
+                       tune_args->code_rate =
+                          as102_fe_get_code_rate(params->u.ofdm.code_rate_LP);
+               }
+
+               dprintk(debug, "\thierarchy: 0x%02x  "
+                               "selected: %s  code_rate_%s: 0x%02x\n",
+                       tune_args->hierarchy,
+                       tune_args->hier_select == HIER_HIGH_PRIORITY ?
+                       "HP" : "LP",
+                       tune_args->hier_select == HIER_HIGH_PRIORITY ?
+                       "HP" : "LP",
+                       tune_args->code_rate);
+       } else {
+               tune_args->code_rate =
+                       as102_fe_get_code_rate(params->u.ofdm.code_rate_HP);
+       }
+}
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c
new file mode 100644 (file)
index 0000000..c019df9
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/ctype.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+
+#include "as102_drv.h"
+#include "as102_fw.h"
+
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+char as102_st_fw1[] = "as102_data1_st.hex";
+char as102_st_fw2[] = "as102_data2_st.hex";
+char as102_dt_fw1[] = "as102_data1_dt.hex";
+char as102_dt_fw2[] = "as102_data2_dt.hex";
+
+static unsigned char atohx(unsigned char *dst, char *src)
+{
+       unsigned char value = 0;
+
+       char msb = tolower(*src) - '0';
+       char lsb = tolower(*(src + 1)) - '0';
+
+       if (msb > 9)
+               msb -= 7;
+       if (lsb > 9)
+               lsb -= 7;
+
+       *dst = value = ((msb & 0xF) << 4) | (lsb & 0xF);
+       return value;
+}
+
+/*
+ * Parse INTEL HEX firmware file to extract address and data.
+ */
+static int parse_hex_line(unsigned char *fw_data, unsigned char *addr,
+                         unsigned char *data, int *dataLength,
+                         unsigned char *addr_has_changed) {
+
+       int count = 0;
+       unsigned char *src, dst;
+
+       if (*fw_data++ != ':') {
+               printk(KERN_ERR "invalid firmware file\n");
+               return -EFAULT;
+       }
+
+       /* locate end of line */
+       for (src = fw_data; *src != '\n'; src += 2) {
+               atohx(&dst, src);
+               /* parse line to split addr / data */
+               switch (count) {
+               case 0:
+                       *dataLength = dst;
+                       break;
+               case 1:
+                       addr[2] = dst;
+                       break;
+               case 2:
+                       addr[3] = dst;
+                       break;
+               case 3:
+                       /* check if data is an address */
+                       if (dst == 0x04)
+                               *addr_has_changed = 1;
+                       else
+                               *addr_has_changed = 0;
+                       break;
+               case  4:
+               case  5:
+                       if (*addr_has_changed)
+                               addr[(count - 4)] = dst;
+                       else
+                               data[(count - 4)] = dst;
+                       break;
+               default:
+                       data[(count - 4)] = dst;
+                       break;
+               }
+               count++;
+       }
+
+       /* return read value + ':' + '\n' */
+       return (count * 2) + 2;
+}
+
+static int as102_firmware_upload(struct as102_bus_adapter_t *bus_adap,
+                                unsigned char *cmd,
+                                const struct firmware *firmware) {
+
+       struct as10x_fw_pkt_t fw_pkt;
+       int total_read_bytes = 0, errno = 0;
+       unsigned char addr_has_changed = 0;
+
+       ENTER();
+
+       for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
+               int read_bytes = 0, data_len = 0;
+
+               /* parse intel hex line */
+               read_bytes = parse_hex_line(
+                               (u8 *) (firmware->data + total_read_bytes),
+                               fw_pkt.raw.address,
+                               fw_pkt.raw.data,
+                               &data_len,
+                               &addr_has_changed);
+
+               if (read_bytes <= 0)
+                       goto error;
+
+               /* detect the end of file */
+               total_read_bytes += read_bytes;
+               if (total_read_bytes == firmware->size) {
+                       fw_pkt.u.request[0] = 0x00;
+                       fw_pkt.u.request[1] = 0x03;
+
+                       /* send EOF command */
+                       errno = bus_adap->ops->upload_fw_pkt(bus_adap,
+                                                            (uint8_t *)
+                                                            &fw_pkt, 2, 0);
+                       if (errno < 0)
+                               goto error;
+               } else {
+                       if (!addr_has_changed) {
+                               /* prepare command to send */
+                               fw_pkt.u.request[0] = 0x00;
+                               fw_pkt.u.request[1] = 0x01;
+
+                               data_len += sizeof(fw_pkt.u.request);
+                               data_len += sizeof(fw_pkt.raw.address);
+
+                               /* send cmd to device */
+                               errno = bus_adap->ops->upload_fw_pkt(bus_adap,
+                                                                    (uint8_t *)
+                                                                    &fw_pkt,
+                                                                    data_len,
+                                                                    0);
+                               if (errno < 0)
+                                       goto error;
+                       }
+               }
+       }
+error:
+       LEAVE();
+       return (errno == 0) ? total_read_bytes : errno;
+}
+
+int as102_fw_upload(struct as102_bus_adapter_t *bus_adap)
+{
+       int errno = -EFAULT;
+       const struct firmware *firmware;
+       unsigned char *cmd_buf = NULL;
+       char *fw1, *fw2;
+
+#if defined(CONFIG_AS102_USB)
+       struct usb_device *dev = bus_adap->usb_dev;
+#endif
+#if defined(CONFIG_AS102_SPI)
+       struct spi_device *dev = bus_adap->spi_dev;
+#endif
+       ENTER();
+
+       /* select fw file to upload */
+       if (dual_tuner) {
+               fw1 = as102_dt_fw1;
+               fw2 = as102_dt_fw2;
+       } else {
+               fw1 = as102_st_fw1;
+               fw2 = as102_st_fw2;
+       }
+
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+       /* allocate buffer to store firmware upload command and data */
+       cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL);
+       if (cmd_buf == NULL) {
+               errno = -ENOMEM;
+               goto error;
+       }
+
+       /* request kernel to locate firmware file: part1 */
+       errno = request_firmware(&firmware, fw1, &dev->dev);
+       if (errno < 0) {
+               printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
+                                DRIVER_NAME, fw1);
+               goto error;
+       }
+
+       /* initiate firmware upload */
+       errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
+       if (errno < 0) {
+               printk(KERN_ERR "%s: error during firmware upload part1\n",
+                                DRIVER_NAME);
+               goto error;
+       }
+
+       printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
+                        DRIVER_NAME, fw1);
+       release_firmware(firmware);
+
+       /* wait for boot to complete */
+       mdelay(100);
+
+       /* request kernel to locate firmware file: part2 */
+       errno = request_firmware(&firmware, fw2, &dev->dev);
+       if (errno < 0) {
+               printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
+                                DRIVER_NAME, fw2);
+               goto error;
+       }
+
+       /* initiate firmware upload */
+       errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
+       if (errno < 0) {
+               printk(KERN_ERR "%s: error during firmware upload part2\n",
+                                DRIVER_NAME);
+               goto error;
+       }
+
+       printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
+                       DRIVER_NAME, fw2);
+error:
+       /* free data buffer */
+       kfree(cmd_buf);
+       /* release firmware if needed */
+       if (firmware != NULL)
+               release_firmware(firmware);
+#endif
+       LEAVE();
+       return errno;
+}
+#endif
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.h b/drivers/staging/media/as102/as102_fw.h
new file mode 100644 (file)
index 0000000..27e5347
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#define MAX_FW_PKT_SIZE        64
+
+extern int dual_tuner;
+
+#pragma pack(1)
+struct as10x_raw_fw_pkt {
+       unsigned char address[4];
+       unsigned char data[MAX_FW_PKT_SIZE - 6];
+};
+
+struct as10x_fw_pkt_t {
+       union {
+               unsigned char request[2];
+               unsigned char length[2];
+       } u;
+       struct as10x_raw_fw_pkt raw;
+};
+#pragma pack()
+
+#ifdef __KERNEL__
+int as102_fw_upload(struct as102_bus_adapter_t *bus_adap);
+#endif
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c
new file mode 100644 (file)
index 0000000..264be2d
--- /dev/null
@@ -0,0 +1,478 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/usb.h>
+
+#include "as102_drv.h"
+#include "as102_usb_drv.h"
+#include "as102_fw.h"
+
+static void as102_usb_disconnect(struct usb_interface *interface);
+static int as102_usb_probe(struct usb_interface *interface,
+                          const struct usb_device_id *id);
+
+static int as102_usb_start_stream(struct as102_dev_t *dev);
+static void as102_usb_stop_stream(struct as102_dev_t *dev);
+
+static int as102_open(struct inode *inode, struct file *file);
+static int as102_release(struct inode *inode, struct file *file);
+
+static struct usb_device_id as102_usb_id_table[] = {
+       { USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) },
+       { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) },
+       { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) },
+       { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) },
+       { } /* Terminating entry */
+};
+
+/* Note that this table must always have the same number of entries as the
+   as102_usb_id_table struct */
+static const char *as102_device_names[] = {
+       AS102_REFERENCE_DESIGN,
+       AS102_PCTV_74E,
+       AS102_ELGATO_EYETV_DTT_NAME,
+       AS102_NBOX_DVBT_DONGLE_NAME,
+       NULL /* Terminating entry */
+};
+
+struct usb_driver as102_usb_driver = {
+       .name       =  DRIVER_FULL_NAME,
+       .probe      =  as102_usb_probe,
+       .disconnect =  as102_usb_disconnect,
+       .id_table   =  as102_usb_id_table
+};
+
+static const struct file_operations as102_dev_fops = {
+       .owner   = THIS_MODULE,
+       .open    = as102_open,
+       .release = as102_release,
+};
+
+static struct usb_class_driver as102_usb_class_driver = {
+       .name           = "aton2-%d",
+       .fops           = &as102_dev_fops,
+       .minor_base     = AS102_DEVICE_MAJOR,
+};
+
+static int as102_usb_xfer_cmd(struct as102_bus_adapter_t *bus_adap,
+                             unsigned char *send_buf, int send_buf_len,
+                             unsigned char *recv_buf, int recv_buf_len)
+{
+       int ret = 0;
+       ENTER();
+
+       if (send_buf != NULL) {
+               ret = usb_control_msg(bus_adap->usb_dev,
+                                     usb_sndctrlpipe(bus_adap->usb_dev, 0),
+                                     AS102_USB_DEVICE_TX_CTRL_CMD,
+                                     USB_DIR_OUT | USB_TYPE_VENDOR |
+                                     USB_RECIP_DEVICE,
+                                     bus_adap->cmd_xid, /* value */
+                                     0, /* index */
+                                     send_buf, send_buf_len,
+                                     USB_CTRL_SET_TIMEOUT /* 200 */);
+               if (ret < 0) {
+                       dprintk(debug, "usb_control_msg(send) failed, err %i\n",
+                                       ret);
+                       return ret;
+               }
+
+               if (ret != send_buf_len) {
+                       dprintk(debug, "only wrote %d of %d bytes\n",
+                                       ret, send_buf_len);
+                       return -1;
+               }
+       }
+
+       if (recv_buf != NULL) {
+#ifdef TRACE
+               dprintk(debug, "want to read: %d bytes\n", recv_buf_len);
+#endif
+               ret = usb_control_msg(bus_adap->usb_dev,
+                                     usb_rcvctrlpipe(bus_adap->usb_dev, 0),
+                                     AS102_USB_DEVICE_RX_CTRL_CMD,
+                                     USB_DIR_IN | USB_TYPE_VENDOR |
+                                     USB_RECIP_DEVICE,
+                                     bus_adap->cmd_xid, /* value */
+                                     0, /* index */
+                                     recv_buf, recv_buf_len,
+                                     USB_CTRL_GET_TIMEOUT /* 200 */);
+               if (ret < 0) {
+                       dprintk(debug, "usb_control_msg(recv) failed, err %i\n",
+                                       ret);
+                       return ret;
+               }
+#ifdef TRACE
+               dprintk(debug, "read %d bytes\n", recv_buf_len);
+#endif
+       }
+
+       LEAVE();
+       return ret;
+}
+
+static int as102_send_ep1(struct as102_bus_adapter_t *bus_adap,
+                         unsigned char *send_buf,
+                         int send_buf_len,
+                         int swap32)
+{
+       int ret = 0, actual_len;
+
+       ret = usb_bulk_msg(bus_adap->usb_dev,
+                          usb_sndbulkpipe(bus_adap->usb_dev, 1),
+                          send_buf, send_buf_len, &actual_len, 200);
+       if (ret) {
+               dprintk(debug, "usb_bulk_msg(send) failed, err %i\n", ret);
+               return ret;
+       }
+
+       if (actual_len != send_buf_len) {
+               dprintk(debug, "only wrote %d of %d bytes\n",
+                               actual_len, send_buf_len);
+               return -1;
+       }
+       return ret ? ret : actual_len;
+}
+
+static int as102_read_ep2(struct as102_bus_adapter_t *bus_adap,
+                  unsigned char *recv_buf, int recv_buf_len)
+{
+       int ret = 0, actual_len;
+
+       if (recv_buf == NULL)
+               return -EINVAL;
+
+       ret = usb_bulk_msg(bus_adap->usb_dev,
+                          usb_rcvbulkpipe(bus_adap->usb_dev, 2),
+                          recv_buf, recv_buf_len, &actual_len, 200);
+       if (ret) {
+               dprintk(debug, "usb_bulk_msg(recv) failed, err %i\n", ret);
+               return ret;
+       }
+
+       if (actual_len != recv_buf_len) {
+               dprintk(debug, "only read %d of %d bytes\n",
+                               actual_len, recv_buf_len);
+               return -1;
+       }
+       return ret ? ret : actual_len;
+}
+
+struct as102_priv_ops_t as102_priv_ops = {
+       .upload_fw_pkt  = as102_send_ep1,
+       .xfer_cmd       = as102_usb_xfer_cmd,
+       .as102_read_ep2 = as102_read_ep2,
+       .start_stream   = as102_usb_start_stream,
+       .stop_stream    = as102_usb_stop_stream,
+};
+
+static int as102_submit_urb_stream(struct as102_dev_t *dev, struct urb *urb)
+{
+       int err;
+
+       usb_fill_bulk_urb(urb,
+                         dev->bus_adap.usb_dev,
+                         usb_rcvbulkpipe(dev->bus_adap.usb_dev, 0x2),
+                         urb->transfer_buffer,
+                         AS102_USB_BUF_SIZE,
+                         as102_urb_stream_irq,
+                         dev);
+
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err)
+               dprintk(debug, "%s: usb_submit_urb failed\n", __func__);
+
+       return err;
+}
+
+void as102_urb_stream_irq(struct urb *urb)
+{
+       struct as102_dev_t *as102_dev = urb->context;
+
+       if (urb->actual_length > 0) {
+               dvb_dmx_swfilter(&as102_dev->dvb_dmx,
+                                urb->transfer_buffer,
+                                urb->actual_length);
+       } else {
+               if (urb->actual_length == 0)
+                       memset(urb->transfer_buffer, 0, AS102_USB_BUF_SIZE);
+       }
+
+       /* is not stopped, re-submit urb */
+       if (as102_dev->streaming)
+               as102_submit_urb_stream(as102_dev, urb);
+}
+
+static void as102_free_usb_stream_buffer(struct as102_dev_t *dev)
+{
+       int i;
+
+       ENTER();
+
+       for (i = 0; i < MAX_STREAM_URB; i++)
+               usb_free_urb(dev->stream_urb[i]);
+
+       usb_free_coherent(dev->bus_adap.usb_dev,
+                       MAX_STREAM_URB * AS102_USB_BUF_SIZE,
+                       dev->stream,
+                       dev->dma_addr);
+       LEAVE();
+}
+
+static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev)
+{
+       int i, ret = 0;
+
+       ENTER();
+
+       dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev,
+                                      MAX_STREAM_URB * AS102_USB_BUF_SIZE,
+                                      GFP_KERNEL,
+                                      &dev->dma_addr);
+       if (!dev->stream) {
+               dprintk(debug, "%s: usb_buffer_alloc failed\n", __func__);
+               return -ENOMEM;
+       }
+
+       memset(dev->stream, 0, MAX_STREAM_URB * AS102_USB_BUF_SIZE);
+
+       /* init urb buffers */
+       for (i = 0; i < MAX_STREAM_URB; i++) {
+               struct urb *urb;
+
+               urb = usb_alloc_urb(0, GFP_ATOMIC);
+               if (urb == NULL) {
+                       dprintk(debug, "%s: usb_alloc_urb failed\n", __func__);
+                       as102_free_usb_stream_buffer(dev);
+                       return -ENOMEM;
+               }
+
+               urb->transfer_buffer = dev->stream + (i * AS102_USB_BUF_SIZE);
+               urb->transfer_buffer_length = AS102_USB_BUF_SIZE;
+
+               dev->stream_urb[i] = urb;
+       }
+       LEAVE();
+       return ret;
+}
+
+static void as102_usb_stop_stream(struct as102_dev_t *dev)
+{
+       int i;
+
+       for (i = 0; i < MAX_STREAM_URB; i++)
+               usb_kill_urb(dev->stream_urb[i]);
+}
+
+static int as102_usb_start_stream(struct as102_dev_t *dev)
+{
+       int i, ret = 0;
+
+       for (i = 0; i < MAX_STREAM_URB; i++) {
+               ret = as102_submit_urb_stream(dev, dev->stream_urb[i]);
+               if (ret) {
+                       as102_usb_stop_stream(dev);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static void as102_usb_release(struct kref *kref)
+{
+       struct as102_dev_t *as102_dev;
+
+       ENTER();
+
+       as102_dev = container_of(kref, struct as102_dev_t, kref);
+       if (as102_dev != NULL) {
+               usb_put_dev(as102_dev->bus_adap.usb_dev);
+               kfree(as102_dev);
+       }
+
+       LEAVE();
+}
+
+static void as102_usb_disconnect(struct usb_interface *intf)
+{
+       struct as102_dev_t *as102_dev;
+
+       ENTER();
+
+       /* extract as102_dev_t from usb_device private data */
+       as102_dev = usb_get_intfdata(intf);
+
+       /* unregister dvb layer */
+       as102_dvb_unregister(as102_dev);
+
+       /* free usb buffers */
+       as102_free_usb_stream_buffer(as102_dev);
+
+       usb_set_intfdata(intf, NULL);
+
+       /* usb unregister device */
+       usb_deregister_dev(intf, &as102_usb_class_driver);
+
+       /* decrement usage counter */
+       kref_put(&as102_dev->kref, as102_usb_release);
+
+       printk(KERN_INFO "%s: device has been disconnected\n", DRIVER_NAME);
+
+       LEAVE();
+}
+
+static int as102_usb_probe(struct usb_interface *intf,
+                          const struct usb_device_id *id)
+{
+       int ret;
+       struct as102_dev_t *as102_dev;
+       int i;
+
+       ENTER();
+
+       as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL);
+       if (as102_dev == NULL) {
+               err("%s: kzalloc failed", __func__);
+               return -ENOMEM;
+       }
+
+       /* This should never actually happen */
+       if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) !=
+           (sizeof(as102_device_names) / sizeof(const char *))) {
+               printk(KERN_ERR "Device names table invalid size");
+               return -EINVAL;
+       }
+
+       /* Assign the user-friendly device name */
+       for (i = 0; i < (sizeof(as102_usb_id_table) /
+                        sizeof(struct usb_device_id)); i++) {
+               if (id == &as102_usb_id_table[i])
+                       as102_dev->name = as102_device_names[i];
+       }
+
+       if (as102_dev->name == NULL)
+               as102_dev->name = "Unknown AS102 device";
+
+       /* set private callback functions */
+       as102_dev->bus_adap.ops = &as102_priv_ops;
+
+       /* init cmd token for usb bus */
+       as102_dev->bus_adap.cmd = &as102_dev->bus_adap.token.usb.c;
+       as102_dev->bus_adap.rsp = &as102_dev->bus_adap.token.usb.r;
+
+       /* init kernel device reference */
+       kref_init(&as102_dev->kref);
+
+       /* store as102 device to usb_device private data */
+       usb_set_intfdata(intf, (void *) as102_dev);
+
+       /* store in as102 device the usb_device pointer */
+       as102_dev->bus_adap.usb_dev = usb_get_dev(interface_to_usbdev(intf));
+
+       /* we can register the device now, as it is ready */
+       ret = usb_register_dev(intf, &as102_usb_class_driver);
+       if (ret < 0) {
+               /* something prevented us from registering this driver */
+               err("%s: usb_register_dev() failed (errno = %d)",
+                   __func__, ret);
+               goto failed;
+       }
+
+       printk(KERN_INFO "%s: device has been detected\n", DRIVER_NAME);
+
+       /* request buffer allocation for streaming */
+       ret = as102_alloc_usb_stream_buffer(as102_dev);
+       if (ret != 0)
+               goto failed;
+
+       /* register dvb layer */
+       ret = as102_dvb_register(as102_dev);
+
+       LEAVE();
+       return ret;
+
+failed:
+       usb_set_intfdata(intf, NULL);
+       kfree(as102_dev);
+       return ret;
+}
+
+static int as102_open(struct inode *inode, struct file *file)
+{
+       int ret = 0, minor = 0;
+       struct usb_interface *intf = NULL;
+       struct as102_dev_t *dev = NULL;
+
+       ENTER();
+
+       /* read minor from inode */
+       minor = iminor(inode);
+
+       /* fetch device from usb interface */
+       intf = usb_find_interface(&as102_usb_driver, minor);
+       if (intf == NULL) {
+               printk(KERN_ERR "%s: can't find device for minor %d\n",
+                               __func__, minor);
+               ret = -ENODEV;
+               goto exit;
+       }
+
+       /* get our device */
+       dev = usb_get_intfdata(intf);
+       if (dev == NULL) {
+               ret = -EFAULT;
+               goto exit;
+       }
+
+       /* save our device object in the file's private structure */
+       file->private_data = dev;
+
+       /* increment our usage count for the device */
+       kref_get(&dev->kref);
+
+exit:
+       LEAVE();
+       return ret;
+}
+
+static int as102_release(struct inode *inode, struct file *file)
+{
+       int ret = 0;
+       struct as102_dev_t *dev = NULL;
+
+       ENTER();
+
+       dev = file->private_data;
+       if (dev != NULL) {
+               /* decrement the count on our device */
+               kref_put(&dev->kref, as102_usb_release);
+       }
+
+       LEAVE();
+       return ret;
+}
+
+MODULE_DEVICE_TABLE(usb, as102_usb_id_table);
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h
new file mode 100644 (file)
index 0000000..fb1fc41
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/version.h>
+
+#ifndef _AS102_USB_DRV_H_
+#define _AS102_USB_DRV_H_
+
+#define AS102_USB_DEVICE_TX_CTRL_CMD   0xF1
+#define AS102_USB_DEVICE_RX_CTRL_CMD   0xF2
+
+/* define these values to match the supported devices */
+
+/* Abilis system: "TITAN" */
+#define AS102_REFERENCE_DESIGN         "Abilis Systems DVB-Titan"
+#define AS102_USB_DEVICE_VENDOR_ID     0x1BA6
+#define AS102_USB_DEVICE_PID_0001      0x0001
+
+/* PCTV Systems: PCTV picoStick (74e) */
+#define AS102_PCTV_74E                 "PCTV Systems picoStick (74e)"
+#define PCTV_74E_USB_VID               0x2013
+#define PCTV_74E_USB_PID               0x0246
+
+/* Elgato: EyeTV DTT Deluxe */
+#define AS102_ELGATO_EYETV_DTT_NAME    "Elgato EyeTV DTT Deluxe"
+#define ELGATO_EYETV_DTT_USB_VID       0x0fd9
+#define ELGATO_EYETV_DTT_USB_PID       0x002c
+
+/* nBox: nBox DVB-T Dongle */
+#define AS102_NBOX_DVBT_DONGLE_NAME    "nBox DVB-T Dongle"
+#define NBOX_DVBT_DONGLE_USB_VID       0x0b89
+#define NBOX_DVBT_DONGLE_USB_PID       0x0007
+
+void as102_urb_stream_irq(struct urb *urb);
+
+struct as10x_usb_token_cmd_t {
+       /* token cmd */
+       struct as10x_cmd_t c;
+       /* token response */
+       struct as10x_cmd_t r;
+};
+#endif
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c
new file mode 100644 (file)
index 0000000..0dcba80
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include "as102_drv.h"
+#include "as10x_types.h"
+#include "as10x_cmd.h"
+
+/**
+ * as10x_cmd_turn_on - send turn on command to AS10x
+ * @phandle:   pointer to AS10x handle
+ *
+ * Return 0 when no error, < 0 in case of error.
+ */
+int as10x_cmd_turn_on(as10x_handle_t *phandle)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.turn_on.req));
+
+       /* fill command */
+       pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+                                              sizeof(pcmd->body.turn_on.req) +
+                                              HEADER_SIZE,
+                                              (uint8_t *) prsp,
+                                              sizeof(prsp->body.turn_on.rsp) +
+                                              HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNON_RSP);
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_turn_off - send turn off command to AS10x
+ * @phandle:   pointer to AS10x handle
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_turn_off(as10x_handle_t *phandle)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.turn_off.req));
+
+       /* fill command */
+       pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(
+                       phandle, (uint8_t *) pcmd,
+                       sizeof(pcmd->body.turn_off.req) + HEADER_SIZE,
+                       (uint8_t *) prsp,
+                       sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNOFF_RSP);
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_set_tune - send set tune command to AS10x
+ * @phandle: pointer to AS10x handle
+ * @ptune:   tune parameters
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_set_tune(as10x_handle_t *phandle, struct as10x_tune_args *ptune)
+{
+       int error;
+       struct as10x_cmd_t *preq, *prsp;
+
+       ENTER();
+
+       preq = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(preq, (++phandle->cmd_xid),
+                       sizeof(preq->body.set_tune.req));
+
+       /* fill command */
+       preq->body.set_tune.req.proc_id = cpu_to_le16(CONTROL_PROC_SETTUNE);
+       preq->body.set_tune.req.args.freq = cpu_to_le32(ptune->freq);
+       preq->body.set_tune.req.args.bandwidth = ptune->bandwidth;
+       preq->body.set_tune.req.args.hier_select = ptune->hier_select;
+       preq->body.set_tune.req.args.constellation = ptune->constellation;
+       preq->body.set_tune.req.args.hierarchy = ptune->hierarchy;
+       preq->body.set_tune.req.args.interleaving_mode  =
+               ptune->interleaving_mode;
+       preq->body.set_tune.req.args.code_rate  = ptune->code_rate;
+       preq->body.set_tune.req.args.guard_interval = ptune->guard_interval;
+       preq->body.set_tune.req.args.transmission_mode  =
+               ptune->transmission_mode;
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(phandle,
+                                              (uint8_t *) preq,
+                                              sizeof(preq->body.set_tune.req)
+                                              + HEADER_SIZE,
+                                              (uint8_t *) prsp,
+                                              sizeof(prsp->body.set_tune.rsp)
+                                              + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_SETTUNE_RSP);
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_get_tune_status - send get tune status command to AS10x
+ * @phandle: pointer to AS10x handle
+ * @pstatus: pointer to updated status structure of the current tune
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_get_tune_status(as10x_handle_t *phandle,
+                             struct as10x_tune_status *pstatus)
+{
+       int error;
+       struct as10x_cmd_t  *preq, *prsp;
+
+       ENTER();
+
+       preq = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(preq, (++phandle->cmd_xid),
+                       sizeof(preq->body.get_tune_status.req));
+
+       /* fill command */
+       preq->body.get_tune_status.req.proc_id =
+               cpu_to_le16(CONTROL_PROC_GETTUNESTAT);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(
+                       phandle,
+                       (uint8_t *) preq,
+                       sizeof(preq->body.get_tune_status.req) + HEADER_SIZE,
+                       (uint8_t *) prsp,
+                       sizeof(prsp->body.get_tune_status.rsp) + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTUNESTAT_RSP);
+       if (error < 0)
+               goto out;
+
+       /* Response OK -> get response data */
+       pstatus->tune_state = prsp->body.get_tune_status.rsp.sts.tune_state;
+       pstatus->signal_strength  =
+               le16_to_cpu(prsp->body.get_tune_status.rsp.sts.signal_strength);
+       pstatus->PER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.PER);
+       pstatus->BER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.BER);
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * send get TPS command to AS10x
+ * @phandle:   pointer to AS10x handle
+ * @ptps:      pointer to TPS parameters structure
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_get_tps(as10x_handle_t *phandle, struct as10x_tps *ptps)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.get_tps.req));
+
+       /* fill command */
+       pcmd->body.get_tune_status.req.proc_id =
+               cpu_to_le16(CONTROL_PROC_GETTPS);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(phandle,
+                                              (uint8_t *) pcmd,
+                                              sizeof(pcmd->body.get_tps.req) +
+                                              HEADER_SIZE,
+                                              (uint8_t *) prsp,
+                                              sizeof(prsp->body.get_tps.rsp) +
+                                              HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTPS_RSP);
+       if (error < 0)
+               goto out;
+
+       /* Response OK -> get response data */
+       ptps->constellation = prsp->body.get_tps.rsp.tps.constellation;
+       ptps->hierarchy = prsp->body.get_tps.rsp.tps.hierarchy;
+       ptps->interleaving_mode = prsp->body.get_tps.rsp.tps.interleaving_mode;
+       ptps->code_rate_HP = prsp->body.get_tps.rsp.tps.code_rate_HP;
+       ptps->code_rate_LP = prsp->body.get_tps.rsp.tps.code_rate_LP;
+       ptps->guard_interval = prsp->body.get_tps.rsp.tps.guard_interval;
+       ptps->transmission_mode  = prsp->body.get_tps.rsp.tps.transmission_mode;
+       ptps->DVBH_mask_HP = prsp->body.get_tps.rsp.tps.DVBH_mask_HP;
+       ptps->DVBH_mask_LP = prsp->body.get_tps.rsp.tps.DVBH_mask_LP;
+       ptps->cell_ID = le16_to_cpu(prsp->body.get_tps.rsp.tps.cell_ID);
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_get_demod_stats - send get demod stats command to AS10x
+ * @phandle:       pointer to AS10x handle
+ * @pdemod_stats:  pointer to demod stats parameters structure
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_get_demod_stats(as10x_handle_t  *phandle,
+                             struct as10x_demod_stats *pdemod_stats)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.get_demod_stats.req));
+
+       /* fill command */
+       pcmd->body.get_demod_stats.req.proc_id =
+               cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(phandle,
+                               (uint8_t *) pcmd,
+                               sizeof(pcmd->body.get_demod_stats.req)
+                               + HEADER_SIZE,
+                               (uint8_t *) prsp,
+                               sizeof(prsp->body.get_demod_stats.rsp)
+                               + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_DEMOD_STATS_RSP);
+       if (error < 0)
+               goto out;
+
+       /* Response OK -> get response data */
+       pdemod_stats->frame_count =
+               le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.frame_count);
+       pdemod_stats->bad_frame_count =
+               le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bad_frame_count);
+       pdemod_stats->bytes_fixed_by_rs =
+               le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bytes_fixed_by_rs);
+       pdemod_stats->mer =
+               le16_to_cpu(prsp->body.get_demod_stats.rsp.stats.mer);
+       pdemod_stats->has_started =
+               prsp->body.get_demod_stats.rsp.stats.has_started;
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_get_impulse_resp - send get impulse response command to AS10x
+ * @phandle:  pointer to AS10x handle
+ * @is_ready: pointer to value indicating when impulse
+ *           response data is ready
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_get_impulse_resp(as10x_handle_t     *phandle,
+                              uint8_t *is_ready)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.get_impulse_rsp.req));
+
+       /* fill command */
+       pcmd->body.get_impulse_rsp.req.proc_id =
+               cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(phandle,
+                                       (uint8_t *) pcmd,
+                                       sizeof(pcmd->body.get_impulse_rsp.req)
+                                       + HEADER_SIZE,
+                                       (uint8_t *) prsp,
+                                       sizeof(prsp->body.get_impulse_rsp.rsp)
+                                       + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_IMPULSE_RESP_RSP);
+       if (error < 0)
+               goto out;
+
+       /* Response OK -> get response data */
+       *is_ready = prsp->body.get_impulse_rsp.rsp.is_ready;
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_build - build AS10x command header
+ * @pcmd:     pointer to AS10x command buffer
+ * @xid:      sequence id of the command
+ * @cmd_len:  length of the command
+ */
+void as10x_cmd_build(struct as10x_cmd_t *pcmd,
+                    uint16_t xid, uint16_t cmd_len)
+{
+       pcmd->header.req_id = cpu_to_le16(xid);
+       pcmd->header.prog = cpu_to_le16(SERVICE_PROG_ID);
+       pcmd->header.version = cpu_to_le16(SERVICE_PROG_VERSION);
+       pcmd->header.data_len = cpu_to_le16(cmd_len);
+}
+
+/**
+ * as10x_rsp_parse - Parse command response
+ * @prsp:       pointer to AS10x command buffer
+ * @proc_id:    id of the command
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id)
+{
+       int error;
+
+       /* extract command error code */
+       error = prsp->body.common.rsp.error;
+
+       if ((error == 0) &&
+           (le16_to_cpu(prsp->body.common.rsp.proc_id) == proc_id)) {
+               return 0;
+       }
+
+       return AS10X_CMD_ERROR;
+}
diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h
new file mode 100644 (file)
index 0000000..01a7163
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _AS10X_CMD_H_
+#define _AS10X_CMD_H_
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#endif
+
+#include "as10x_types.h"
+
+/*********************************/
+/*       MACRO DEFINITIONS       */
+/*********************************/
+#define AS10X_CMD_ERROR -1
+
+#define SERVICE_PROG_ID        0x0002
+#define SERVICE_PROG_VERSION   0x0001
+
+#define HIER_NONE              0x00
+#define HIER_LOW_PRIORITY      0x01
+
+#define HEADER_SIZE (sizeof(struct as10x_cmd_header_t))
+
+/* context request types */
+#define GET_CONTEXT_DATA        1
+#define SET_CONTEXT_DATA        2
+
+/* ODSP suspend modes */
+#define CFG_MODE_ODSP_RESUME  0
+#define CFG_MODE_ODSP_SUSPEND 1
+
+/* Dump memory size */
+#define DUMP_BLOCK_SIZE_MAX   0x20
+
+/*********************************/
+/*     TYPE DEFINITION           */
+/*********************************/
+typedef enum {
+   CONTROL_PROC_TURNON               = 0x0001,
+   CONTROL_PROC_TURNON_RSP           = 0x0100,
+   CONTROL_PROC_SET_REGISTER         = 0x0002,
+   CONTROL_PROC_SET_REGISTER_RSP     = 0x0200,
+   CONTROL_PROC_GET_REGISTER         = 0x0003,
+   CONTROL_PROC_GET_REGISTER_RSP     = 0x0300,
+   CONTROL_PROC_SETTUNE              = 0x000A,
+   CONTROL_PROC_SETTUNE_RSP          = 0x0A00,
+   CONTROL_PROC_GETTUNESTAT          = 0x000B,
+   CONTROL_PROC_GETTUNESTAT_RSP      = 0x0B00,
+   CONTROL_PROC_GETTPS               = 0x000D,
+   CONTROL_PROC_GETTPS_RSP           = 0x0D00,
+   CONTROL_PROC_SETFILTER            = 0x000E,
+   CONTROL_PROC_SETFILTER_RSP        = 0x0E00,
+   CONTROL_PROC_REMOVEFILTER         = 0x000F,
+   CONTROL_PROC_REMOVEFILTER_RSP     = 0x0F00,
+   CONTROL_PROC_GET_IMPULSE_RESP     = 0x0012,
+   CONTROL_PROC_GET_IMPULSE_RESP_RSP = 0x1200,
+   CONTROL_PROC_START_STREAMING      = 0x0013,
+   CONTROL_PROC_START_STREAMING_RSP  = 0x1300,
+   CONTROL_PROC_STOP_STREAMING       = 0x0014,
+   CONTROL_PROC_STOP_STREAMING_RSP   = 0x1400,
+   CONTROL_PROC_GET_DEMOD_STATS      = 0x0015,
+   CONTROL_PROC_GET_DEMOD_STATS_RSP  = 0x1500,
+   CONTROL_PROC_ELNA_CHANGE_MODE     = 0x0016,
+   CONTROL_PROC_ELNA_CHANGE_MODE_RSP = 0x1600,
+   CONTROL_PROC_ODSP_CHANGE_MODE     = 0x0017,
+   CONTROL_PROC_ODSP_CHANGE_MODE_RSP = 0x1700,
+   CONTROL_PROC_AGC_CHANGE_MODE      = 0x0018,
+   CONTROL_PROC_AGC_CHANGE_MODE_RSP  = 0x1800,
+
+   CONTROL_PROC_CONTEXT              = 0x00FC,
+   CONTROL_PROC_CONTEXT_RSP          = 0xFC00,
+   CONTROL_PROC_DUMP_MEMORY          = 0x00FD,
+   CONTROL_PROC_DUMP_MEMORY_RSP      = 0xFD00,
+   CONTROL_PROC_DUMPLOG_MEMORY       = 0x00FE,
+   CONTROL_PROC_DUMPLOG_MEMORY_RSP   = 0xFE00,
+   CONTROL_PROC_TURNOFF              = 0x00FF,
+   CONTROL_PROC_TURNOFF_RSP          = 0xFF00
+} control_proc;
+
+
+#pragma pack(1)
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} TURN_ON;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t err;
+   } rsp;
+} TURN_OFF;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* tune params */
+      struct as10x_tune_args args;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+   } rsp;
+} SET_TUNE;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+      /* tune status */
+      struct as10x_tune_status sts;
+   } rsp;
+} GET_TUNE_STATUS;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+      /* tps details */
+      struct as10x_tps tps;
+   } rsp;
+} GET_TPS;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t  proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+   } rsp;
+} COMMON;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t  proc_id;
+      /* PID to filter */
+      uint16_t  pid;
+      /* stream type (MPE, PSI/SI or PES )*/
+      uint8_t stream_type;
+      /* PID index in filter table */
+      uint8_t idx;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+      /* Filter id */
+      uint8_t filter_id;
+   } rsp;
+} ADD_PID_FILTER;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t  proc_id;
+      /* PID to remove */
+      uint16_t  pid;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+   } rsp;
+} DEL_PID_FILTER;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} START_STREAMING;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} STOP_STREAMING;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* demod stats */
+      struct as10x_demod_stats stats;
+   } rsp;
+} GET_DEMOD_STATS;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* impulse response ready */
+      uint8_t is_ready;
+   } rsp;
+} GET_IMPULSE_RESP;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* value to write (for set context)*/
+      struct as10x_register_value reg_val;
+      /* context tag */
+      uint16_t tag;
+      /* context request type */
+      uint16_t type;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* value read (for get context) */
+      struct as10x_register_value reg_val;
+      /* context request type */
+      uint16_t type;
+      /* error */
+      uint8_t error;
+   } rsp;
+} FW_CONTEXT;
+
+typedef union {
+   /* request */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* register description */
+      struct as10x_register_addr reg_addr;
+      /* register content */
+      struct as10x_register_value reg_val;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} SET_REGISTER;
+
+typedef union {
+   /* request */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* register description */
+      struct as10x_register_addr reg_addr;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* register content */
+      struct as10x_register_value reg_val;
+   } rsp;
+} GET_REGISTER;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* mode */
+      uint8_t mode;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} CFG_CHANGE_MODE;
+
+struct as10x_cmd_header_t {
+   uint16_t req_id;
+   uint16_t prog;
+   uint16_t version;
+   uint16_t data_len;
+};
+
+#define DUMP_BLOCK_SIZE 16
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* dump memory type request */
+      uint8_t dump_req;
+      /* register description */
+      struct as10x_register_addr reg_addr;
+      /* nb blocks to read */
+      uint16_t num_blocks;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* dump response */
+      uint8_t dump_rsp;
+      /* data */
+      union {
+        uint8_t  data8[DUMP_BLOCK_SIZE];
+        uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)];
+        uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)];
+      } u;
+   } rsp;
+} DUMP_MEMORY;
+
+typedef union {
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* dump memory type request */
+      uint8_t dump_req;
+   } req;
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* dump response */
+      uint8_t dump_rsp;
+      /* dump data */
+      uint8_t data[DUMP_BLOCK_SIZE];
+   } rsp;
+} DUMPLOG_MEMORY;
+
+typedef union {
+   /* request */
+   struct {
+      uint16_t proc_id;
+      uint8_t data[64 - sizeof(struct as10x_cmd_header_t) -2 /* proc_id */];
+   } req;
+   /* response */
+   struct {
+      uint16_t proc_id;
+      uint8_t error;
+      uint8_t data[64 - sizeof(struct as10x_cmd_header_t) /* header */
+                     - 2 /* proc_id */ - 1 /* rc */];
+   } rsp;
+} RAW_DATA;
+
+struct as10x_cmd_t {
+   /* header */
+   struct as10x_cmd_header_t header;
+   /* body */
+   union {
+      TURN_ON           turn_on;
+      TURN_OFF          turn_off;
+      SET_TUNE          set_tune;
+      GET_TUNE_STATUS   get_tune_status;
+      GET_TPS           get_tps;
+      COMMON            common;
+      ADD_PID_FILTER    add_pid_filter;
+      DEL_PID_FILTER    del_pid_filter;
+      START_STREAMING   start_streaming;
+      STOP_STREAMING    stop_streaming;
+      GET_DEMOD_STATS   get_demod_stats;
+      GET_IMPULSE_RESP  get_impulse_rsp;
+      FW_CONTEXT        context;
+      SET_REGISTER      set_register;
+      GET_REGISTER      get_register;
+      CFG_CHANGE_MODE   cfg_change_mode;
+      DUMP_MEMORY       dump_memory;
+      DUMPLOG_MEMORY    dumplog_memory;
+      RAW_DATA          raw_data;
+   } body;
+};
+
+struct as10x_token_cmd_t {
+   /* token cmd */
+   struct as10x_cmd_t c;
+   /* token response */
+   struct as10x_cmd_t r;
+};
+#pragma pack()
+
+
+/**************************/
+/* FUNCTION DECLARATION   */
+/**************************/
+
+void as10x_cmd_build(struct as10x_cmd_t *pcmd, uint16_t proc_id,
+                     uint16_t cmd_len);
+int as10x_rsp_parse(struct as10x_cmd_t *r, uint16_t proc_id);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* as10x cmd */
+int as10x_cmd_turn_on(as10x_handle_t *phandle);
+int as10x_cmd_turn_off(as10x_handle_t *phandle);
+
+int as10x_cmd_set_tune(as10x_handle_t *phandle,
+                      struct as10x_tune_args *ptune);
+
+int as10x_cmd_get_tune_status(as10x_handle_t *phandle,
+                             struct as10x_tune_status *pstatus);
+
+int as10x_cmd_get_tps(as10x_handle_t *phandle,
+                     struct as10x_tps *ptps);
+
+int as10x_cmd_get_demod_stats(as10x_handle_t  *phandle,
+                             struct as10x_demod_stats *pdemod_stats);
+
+int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle,
+                              uint8_t *is_ready);
+
+/* as10x cmd stream */
+int as10x_cmd_add_PID_filter(as10x_handle_t *phandle,
+                            struct as10x_ts_filter *filter);
+int as10x_cmd_del_PID_filter(as10x_handle_t *phandle,
+                            uint16_t pid_value);
+
+int as10x_cmd_start_streaming(as10x_handle_t *phandle);
+int as10x_cmd_stop_streaming(as10x_handle_t *phandle);
+
+/* as10x cmd cfg */
+int as10x_cmd_set_context(as10x_handle_t *phandle,
+                         uint16_t tag,
+                         uint32_t value);
+int as10x_cmd_get_context(as10x_handle_t *phandle,
+                         uint16_t tag,
+                         uint32_t *pvalue);
+
+int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode);
+int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id);
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* EOF - vim: set textwidth=80 ts=3 sw=3 sts=3 et: */
diff --git a/drivers/staging/media/as102/as10x_cmd_cfg.c b/drivers/staging/media/as102/as10x_cmd_cfg.c
new file mode 100644 (file)
index 0000000..ec6f69f
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include "as102_drv.h"
+#include "as10x_types.h"
+#include "as10x_cmd.h"
+
+/***************************/
+/* FUNCTION DEFINITION     */
+/***************************/
+
+/**
+ * as10x_cmd_get_context - Send get context command to AS10x
+ * @phandle:   pointer to AS10x handle
+ * @tag:       context tag
+ * @pvalue:    pointer where to store context value read
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag,
+                         uint32_t *pvalue)
+{
+       int  error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.context.req));
+
+       /* fill command */
+       pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT);
+       pcmd->body.context.req.tag = cpu_to_le16(tag);
+       pcmd->body.context.req.type = cpu_to_le16(GET_CONTEXT_DATA);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error  = phandle->ops->xfer_cmd(phandle,
+                                               (uint8_t *) pcmd,
+                                               sizeof(pcmd->body.context.req)
+                                               + HEADER_SIZE,
+                                               (uint8_t *) prsp,
+                                               sizeof(prsp->body.context.rsp)
+                                               + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response: context command do not follow the common response */
+       /* structure -> specific handling response parse required            */
+       error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
+
+       if (error == 0) {
+               /* Response OK -> get response data */
+               *pvalue = le32_to_cpu(prsp->body.context.rsp.reg_val.u.value32);
+               /* value returned is always a 32-bit value */
+       }
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_set_context - send set context command to AS10x
+ * @phandle:   pointer to AS10x handle
+ * @tag:       context tag
+ * @value:     value to set in context
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag,
+                         uint32_t value)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.context.req));
+
+       /* fill command */
+       pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT);
+       /* pcmd->body.context.req.reg_val.mode initialization is not required */
+       pcmd->body.context.req.reg_val.u.value32 = cpu_to_le32(value);
+       pcmd->body.context.req.tag = cpu_to_le16(tag);
+       pcmd->body.context.req.type = cpu_to_le16(SET_CONTEXT_DATA);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error  = phandle->ops->xfer_cmd(phandle,
+                                               (uint8_t *) pcmd,
+                                               sizeof(pcmd->body.context.req)
+                                               + HEADER_SIZE,
+                                               (uint8_t *) prsp,
+                                               sizeof(prsp->body.context.rsp)
+                                               + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response: context command do not follow the common response */
+       /* structure -> specific handling response parse required            */
+       error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x
+ * @phandle:   pointer to AS10x handle
+ * @mode:      mode selected:
+ *             - ON    : 0x0 => eLNA always ON
+ *             - OFF   : 0x1 => eLNA always OFF
+ *             - AUTO  : 0x2 => eLNA follow hysteresis parameters
+ *                              to be ON or OFF
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.cfg_change_mode.req));
+
+       /* fill command */
+       pcmd->body.cfg_change_mode.req.proc_id =
+               cpu_to_le16(CONTROL_PROC_ELNA_CHANGE_MODE);
+       pcmd->body.cfg_change_mode.req.mode = mode;
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error  = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+                               sizeof(pcmd->body.cfg_change_mode.req)
+                               + HEADER_SIZE, (uint8_t *) prsp,
+                               sizeof(prsp->body.cfg_change_mode.rsp)
+                               + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_ELNA_CHANGE_MODE_RSP);
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_context_rsp_parse - Parse context command response
+ * @prsp:       pointer to AS10x command response buffer
+ * @proc_id:    id of the command
+ *
+ * Since the contex command reponse does not follow the common
+ * response, a specific parse function is required.
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id)
+{
+       int err;
+
+       err = prsp->body.context.rsp.error;
+
+       if ((err == 0) &&
+           (le16_to_cpu(prsp->body.context.rsp.proc_id) == proc_id)) {
+               return 0;
+       }
+       return AS10X_CMD_ERROR;
+}
diff --git a/drivers/staging/media/as102/as10x_cmd_stream.c b/drivers/staging/media/as102/as10x_cmd_stream.c
new file mode 100644 (file)
index 0000000..045c706
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include "as102_drv.h"
+#include "as10x_cmd.h"
+
+/**
+ * as10x_cmd_add_PID_filter - send add filter command to AS10x
+ * @phandle:   pointer to AS10x handle
+ * @filter:    TSFilter filter for DVB-T
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_add_PID_filter(as10x_handle_t *phandle,
+                            struct as10x_ts_filter *filter)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.add_pid_filter.req));
+
+       /* fill command */
+       pcmd->body.add_pid_filter.req.proc_id =
+               cpu_to_le16(CONTROL_PROC_SETFILTER);
+       pcmd->body.add_pid_filter.req.pid = cpu_to_le16(filter->pid);
+       pcmd->body.add_pid_filter.req.stream_type = filter->type;
+
+       if (filter->idx < 16)
+               pcmd->body.add_pid_filter.req.idx = filter->idx;
+       else
+               pcmd->body.add_pid_filter.req.idx = 0xFF;
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+                               sizeof(pcmd->body.add_pid_filter.req)
+                               + HEADER_SIZE, (uint8_t *) prsp,
+                               sizeof(prsp->body.add_pid_filter.rsp)
+                               + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_SETFILTER_RSP);
+
+       if (error == 0) {
+               /* Response OK -> get response data */
+               filter->idx = prsp->body.add_pid_filter.rsp.filter_id;
+       }
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_del_PID_filter - Send delete filter command to AS10x
+ * @phandle:      pointer to AS10x handle
+ * @pid_value:    PID to delete
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_del_PID_filter(as10x_handle_t *phandle,
+                            uint16_t pid_value)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.del_pid_filter.req));
+
+       /* fill command */
+       pcmd->body.del_pid_filter.req.proc_id =
+               cpu_to_le16(CONTROL_PROC_REMOVEFILTER);
+       pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+                               sizeof(pcmd->body.del_pid_filter.req)
+                               + HEADER_SIZE, (uint8_t *) prsp,
+                               sizeof(prsp->body.del_pid_filter.rsp)
+                               + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_REMOVEFILTER_RSP);
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_start_streaming - Send start streaming command to AS10x
+ * @phandle:   pointer to AS10x handle
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_start_streaming(as10x_handle_t *phandle)
+{
+       int error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.start_streaming.req));
+
+       /* fill command */
+       pcmd->body.start_streaming.req.proc_id =
+               cpu_to_le16(CONTROL_PROC_START_STREAMING);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+                               sizeof(pcmd->body.start_streaming.req)
+                               + HEADER_SIZE, (uint8_t *) prsp,
+                               sizeof(prsp->body.start_streaming.rsp)
+                               + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_START_STREAMING_RSP);
+
+out:
+       LEAVE();
+       return error;
+}
+
+/**
+ * as10x_cmd_stop_streaming - Send stop streaming command to AS10x
+ * @phandle:   pointer to AS10x handle
+ *
+ * Return 0 on success or negative value in case of error.
+ */
+int as10x_cmd_stop_streaming(as10x_handle_t *phandle)
+{
+       int8_t error;
+       struct as10x_cmd_t *pcmd, *prsp;
+
+       ENTER();
+
+       pcmd = phandle->cmd;
+       prsp = phandle->rsp;
+
+       /* prepare command */
+       as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+                       sizeof(pcmd->body.stop_streaming.req));
+
+       /* fill command */
+       pcmd->body.stop_streaming.req.proc_id =
+               cpu_to_le16(CONTROL_PROC_STOP_STREAMING);
+
+       /* send command */
+       if (phandle->ops->xfer_cmd) {
+               error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+                               sizeof(pcmd->body.stop_streaming.req)
+                               + HEADER_SIZE, (uint8_t *) prsp,
+                               sizeof(prsp->body.stop_streaming.rsp)
+                               + HEADER_SIZE);
+       } else {
+               error = AS10X_CMD_ERROR;
+       }
+
+       if (error < 0)
+               goto out;
+
+       /* parse response */
+       error = as10x_rsp_parse(prsp, CONTROL_PROC_STOP_STREAMING_RSP);
+
+out:
+       LEAVE();
+       return error;
+}
diff --git a/drivers/staging/media/as102/as10x_handle.h b/drivers/staging/media/as102/as10x_handle.h
new file mode 100644 (file)
index 0000000..4f01a76
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifdef __KERNEL__
+struct as102_bus_adapter_t;
+struct as102_dev_t;
+
+#define as10x_handle_t struct as102_bus_adapter_t
+#include "as10x_cmd.h"
+
+/* values for "mode" field */
+#define REGMODE8         8
+#define REGMODE16        16
+#define REGMODE32        32
+
+struct as102_priv_ops_t {
+       int (*upload_fw_pkt) (struct as102_bus_adapter_t *bus_adap,
+                             unsigned char *buf, int buflen, int swap32);
+
+       int (*send_cmd) (struct as102_bus_adapter_t *bus_adap,
+                        unsigned char *buf, int buflen);
+
+       int (*xfer_cmd) (struct as102_bus_adapter_t *bus_adap,
+                        unsigned char *send_buf, int send_buf_len,
+                        unsigned char *recv_buf, int recv_buf_len);
+/*
+       int (*pid_filter) (struct as102_bus_adapter_t *bus_adap,
+                          int index, u16 pid, int onoff);
+*/
+       int (*start_stream) (struct as102_dev_t *dev);
+       void (*stop_stream) (struct as102_dev_t *dev);
+
+       int (*reset_target) (struct as102_bus_adapter_t *bus_adap);
+
+       int (*read_write)(struct as102_bus_adapter_t *bus_adap, uint8_t mode,
+                         uint32_t rd_addr, uint16_t rd_len,
+                         uint32_t wr_addr, uint16_t wr_len);
+
+       int (*as102_read_ep2) (struct as102_bus_adapter_t *bus_adap,
+                              unsigned char *recv_buf,
+                              int recv_buf_len);
+};
+#endif
diff --git a/drivers/staging/media/as102/as10x_types.h b/drivers/staging/media/as102/as10x_types.h
new file mode 100644 (file)
index 0000000..3dedb3c
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _AS10X_TYPES_H_
+#define _AS10X_TYPES_H_
+
+#include "as10x_handle.h"
+
+/*********************************/
+/*       MACRO DEFINITIONS       */
+/*********************************/
+
+/* bandwidth constant values */
+#define BW_5_MHZ           0x00
+#define BW_6_MHZ           0x01
+#define BW_7_MHZ           0x02
+#define BW_8_MHZ           0x03
+
+/* hierarchy priority selection values */
+#define HIER_NO_PRIORITY   0x00
+#define HIER_LOW_PRIORITY  0x01
+#define HIER_HIGH_PRIORITY 0x02
+
+/* constellation available values */
+#define CONST_QPSK         0x00
+#define CONST_QAM16        0x01
+#define CONST_QAM64        0x02
+#define CONST_UNKNOWN      0xFF
+
+/* hierarchy available values */
+#define HIER_NONE         0x00
+#define HIER_ALPHA_1      0x01
+#define HIER_ALPHA_2      0x02
+#define HIER_ALPHA_4      0x03
+#define HIER_UNKNOWN      0xFF
+
+/* interleaving available values */
+#define INTLV_NATIVE      0x00
+#define INTLV_IN_DEPTH    0x01
+#define INTLV_UNKNOWN     0xFF
+
+/* code rate available values */
+#define CODE_RATE_1_2     0x00
+#define CODE_RATE_2_3     0x01
+#define CODE_RATE_3_4     0x02
+#define CODE_RATE_5_6     0x03
+#define CODE_RATE_7_8     0x04
+#define CODE_RATE_UNKNOWN 0xFF
+
+/* guard interval available values */
+#define GUARD_INT_1_32    0x00
+#define GUARD_INT_1_16    0x01
+#define GUARD_INT_1_8     0x02
+#define GUARD_INT_1_4     0x03
+#define GUARD_UNKNOWN     0xFF
+
+/* transmission mode available values */
+#define TRANS_MODE_2K      0x00
+#define TRANS_MODE_8K      0x01
+#define TRANS_MODE_4K      0x02
+#define TRANS_MODE_UNKNOWN 0xFF
+
+/* DVBH signalling available values */
+#define TIMESLICING_PRESENT   0x01
+#define MPE_FEC_PRESENT       0x02
+
+/* tune state available */
+#define TUNE_STATUS_NOT_TUNED       0x00
+#define TUNE_STATUS_IDLE            0x01
+#define TUNE_STATUS_LOCKING         0x02
+#define TUNE_STATUS_SIGNAL_DVB_OK   0x03
+#define TUNE_STATUS_STREAM_DETECTED 0x04
+#define TUNE_STATUS_STREAM_TUNED    0x05
+#define TUNE_STATUS_ERROR           0xFF
+
+/* available TS FID filter types */
+#define TS_PID_TYPE_TS       0
+#define TS_PID_TYPE_PSI_SI   1
+#define TS_PID_TYPE_MPE      2
+
+/* number of echos available */
+#define MAX_ECHOS   15
+
+/* Context types */
+#define CONTEXT_LNA                   1010
+#define CONTEXT_ELNA_HYSTERESIS       4003
+#define CONTEXT_ELNA_GAIN             4004
+#define CONTEXT_MER_THRESHOLD         5005
+#define CONTEXT_MER_OFFSET            5006
+#define CONTEXT_IR_STATE              7000
+#define CONTEXT_TSOUT_MSB_FIRST       7004
+#define CONTEXT_TSOUT_FALLING_EDGE    7005
+
+/* Configuration modes */
+#define CFG_MODE_ON     0
+#define CFG_MODE_OFF    1
+#define CFG_MODE_AUTO   2
+
+#pragma pack(1)
+struct as10x_tps {
+   uint8_t constellation;
+   uint8_t hierarchy;
+   uint8_t interleaving_mode;
+   uint8_t code_rate_HP;
+   uint8_t code_rate_LP;
+   uint8_t guard_interval;
+   uint8_t transmission_mode;
+   uint8_t DVBH_mask_HP;
+   uint8_t DVBH_mask_LP;
+   uint16_t cell_ID;
+};
+
+struct as10x_tune_args {
+   /* frequency */
+   uint32_t freq;
+   /* bandwidth */
+   uint8_t bandwidth;
+   /* hierarchy selection */
+   uint8_t hier_select;
+   /* constellation */
+   uint8_t constellation;
+   /* hierarchy */
+   uint8_t hierarchy;
+   /* interleaving mode */
+   uint8_t interleaving_mode;
+   /* code rate */
+   uint8_t code_rate;
+   /* guard interval */
+   uint8_t guard_interval;
+   /* transmission mode */
+   uint8_t transmission_mode;
+};
+
+struct as10x_tune_status {
+   /* tune status */
+   uint8_t tune_state;
+   /* signal strength */
+   int16_t signal_strength;
+   /* packet error rate 10^-4 */
+   uint16_t PER;
+   /* bit error rate 10^-4 */
+   uint16_t BER;
+};
+
+struct as10x_demod_stats {
+   /* frame counter */
+   uint32_t frame_count;
+   /* Bad frame counter */
+   uint32_t bad_frame_count;
+   /* Number of wrong bytes fixed by Reed-Solomon */
+   uint32_t bytes_fixed_by_rs;
+   /* Averaged MER */
+   uint16_t mer;
+   /* statistics calculation state indicator (started or not) */
+   uint8_t has_started;
+};
+
+struct as10x_ts_filter {
+   uint16_t pid;  /** valid PID value 0x00 : 0x2000 */
+   uint8_t  type; /** Red TS_PID_TYPE_<N> values */
+   uint8_t  idx;  /** index in filtering table */
+};
+
+struct as10x_register_value {
+   uint8_t       mode;
+   union {
+      uint8_t    value8;    /* 8 bit value */
+      uint16_t   value16;   /* 16 bit value */
+      uint32_t   value32;   /* 32 bit value */
+   }u;
+};
+
+#pragma pack()
+
+struct as10x_register_addr {
+   /* register addr */
+   uint32_t addr;
+   /* register mode access */
+   uint8_t mode;
+};
+
+
+#endif
index fa9a286..da42f32 100644 (file)
@@ -5,7 +5,7 @@
 # selected by any of the users.
 config ORE
        tristate
-       depends on EXOFS_FS
+       depends on EXOFS_FS || PNFS_OBJLAYOUT
        select ASYNC_XOR
        default SCSI_OSD_ULD
 
index 918ad64..726e59a 100644 (file)
@@ -488,17 +488,18 @@ static __be32 decode_recallany_args(struct svc_rqst *rqstp,
                                      struct xdr_stream *xdr,
                                      struct cb_recallanyargs *args)
 {
-       __be32 *p;
+       uint32_t bitmap[2];
+       __be32 *p, status;
 
        args->craa_addr = svc_addr(rqstp);
        p = read_buf(xdr, 4);
        if (unlikely(p == NULL))
                return htonl(NFS4ERR_BADXDR);
        args->craa_objs_to_keep = ntohl(*p++);
-       p = read_buf(xdr, 4);
-       if (unlikely(p == NULL))
-               return htonl(NFS4ERR_BADXDR);
-       args->craa_type_mask = ntohl(*p);
+       status = decode_bitmap(xdr, bitmap);
+       if (unlikely(status))
+               return status;
+       args->craa_type_mask = bitmap[0];
 
        return 0;
 }
@@ -986,4 +987,5 @@ struct svc_version nfs4_callback_version4 = {
        .vs_proc = nfs4_callback_procedures1,
        .vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
        .vs_dispatch = NULL,
+       .vs_hidden = 1,
 };
index 91c01f0..0a1f831 100644 (file)
@@ -137,11 +137,9 @@ nfs_file_open(struct inode *inode, struct file *filp)
 static int
 nfs_file_release(struct inode *inode, struct file *filp)
 {
-       struct dentry *dentry = filp->f_path.dentry;
-
        dprintk("NFS: release(%s/%s)\n",
-                       dentry->d_parent->d_name.name,
-                       dentry->d_name.name);
+                       filp->f_path.dentry->d_parent->d_name.name,
+                       filp->f_path.dentry->d_name.name);
 
        nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
        return nfs_release(inode, filp);
@@ -228,14 +226,13 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
        struct dentry * dentry = iocb->ki_filp->f_path.dentry;
        struct inode * inode = dentry->d_inode;
        ssize_t result;
-       size_t count = iov_length(iov, nr_segs);
 
        if (iocb->ki_filp->f_flags & O_DIRECT)
                return nfs_file_direct_read(iocb, iov, nr_segs, pos);
 
        dprintk("NFS: read(%s/%s, %lu@%lu)\n",
                dentry->d_parent->d_name.name, dentry->d_name.name,
-               (unsigned long) count, (unsigned long) pos);
+               (unsigned long) iov_length(iov, nr_segs), (unsigned long) pos);
 
        result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
        if (!result) {
index 0911941..12185aa 100644 (file)
@@ -449,9 +449,8 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
 
        fl->dsaddr = dsaddr;
 
-       if (fl->first_stripe_index < 0 ||
-           fl->first_stripe_index >= dsaddr->stripe_count) {
-               dprintk("%s Bad first_stripe_index %d\n",
+       if (fl->first_stripe_index >= dsaddr->stripe_count) {
+               dprintk("%s Bad first_stripe_index %u\n",
                                __func__, fl->first_stripe_index);
                goto out_put;
        }
@@ -552,7 +551,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
 
        /* Note that a zero value for num_fh is legal for STRIPE_SPARSE.
         * Futher checking is done in filelayout_check_layout */
-       if (fl->num_fh < 0 || fl->num_fh >
+       if (fl->num_fh >
            max(NFS4_PNFS_MAX_STRIPE_CNT, NFS4_PNFS_MAX_MULTI_CNT))
                goto out_err;
 
index d2ae413..b60fddf 100644 (file)
@@ -5950,6 +5950,7 @@ static void nfs4_layoutcommit_release(void *calldata)
 {
        struct nfs4_layoutcommit_data *data = calldata;
        struct pnfs_layout_segment *lseg, *tmp;
+       unsigned long *bitlock = &NFS_I(data->args.inode)->flags;
 
        pnfs_cleanup_layoutcommit(data);
        /* Matched by references in pnfs_set_layoutcommit */
@@ -5959,6 +5960,11 @@ static void nfs4_layoutcommit_release(void *calldata)
                                       &lseg->pls_flags))
                        put_lseg(lseg);
        }
+
+       clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock);
+       smp_mb__after_clear_bit();
+       wake_up_bit(bitlock, NFS_INO_LAYOUTCOMMITTING);
+
        put_rpccred(data->cred);
        kfree(data);
 }
index 1dce12f..e6161b2 100644 (file)
@@ -6602,8 +6602,6 @@ static int nfs4_xdr_dec_secinfo(struct rpc_rqst *rqstp,
        if (status)
                goto out;
        status = decode_secinfo(xdr, res);
-       if (status)
-               goto out;
 out:
        return status;
 }
index d0cda12..c807ab9 100644 (file)
  */
 
 #include <linux/module.h>
-#include <scsi/osd_initiator.h>
+#include <scsi/osd_ore.h>
 
 #include "objlayout.h"
 
 #define NFSDBG_FACILITY         NFSDBG_PNFS_LD
 
-#define _LLU(x) ((unsigned long long)x)
-
-enum { BIO_MAX_PAGES_KMALLOC =
-               (PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec),
-};
-
 struct objio_dev_ent {
        struct nfs4_deviceid_node id_node;
-       struct osd_dev *od;
+       struct ore_dev od;
 };
 
 static void
@@ -60,8 +54,8 @@ objio_free_deviceid_node(struct nfs4_deviceid_node *d)
 {
        struct objio_dev_ent *de = container_of(d, struct objio_dev_ent, id_node);
 
-       dprintk("%s: free od=%p\n", __func__, de->od);
-       osduld_put_device(de->od);
+       dprintk("%s: free od=%p\n", __func__, de->od.od);
+       osduld_put_device(de->od.od);
        kfree(de);
 }
 
@@ -98,12 +92,12 @@ _dev_list_add(const struct nfs_server *nfss,
                                nfss->pnfs_curr_ld,
                                nfss->nfs_client,
                                d_id);
-       de->od = od;
+       de->od.od = od;
 
        d = nfs4_insert_deviceid_node(&de->id_node);
        n = container_of(d, struct objio_dev_ent, id_node);
        if (n != de) {
-               dprintk("%s: Race with other n->od=%p\n", __func__, n->od);
+               dprintk("%s: Race with other n->od=%p\n", __func__, n->od.od);
                objio_free_deviceid_node(&de->id_node);
                de = n;
        }
@@ -111,28 +105,11 @@ _dev_list_add(const struct nfs_server *nfss,
        return de;
 }
 
-struct caps_buffers {
-       u8 caps_key[OSD_CRYPTO_KEYID_SIZE];
-       u8 creds[OSD_CAP_LEN];
-};
-
 struct objio_segment {
        struct pnfs_layout_segment lseg;
 
-       struct pnfs_osd_object_cred *comps;
-
-       unsigned mirrors_p1;
-       unsigned stripe_unit;
-       unsigned group_width;   /* Data stripe_units without integrity comps */
-       u64 group_depth;
-       unsigned group_count;
-
-       unsigned max_io_size;
-
-       unsigned comps_index;
-       unsigned num_comps;
-       /* variable length */
-       struct objio_dev_ent *ods[];
+       struct ore_layout layout;
+       struct ore_components oc;
 };
 
 static inline struct objio_segment *
@@ -141,59 +118,44 @@ OBJIO_LSEG(struct pnfs_layout_segment *lseg)
        return container_of(lseg, struct objio_segment, lseg);
 }
 
-struct objio_state;
-typedef ssize_t (*objio_done_fn)(struct objio_state *ios);
-
 struct objio_state {
        /* Generic layer */
-       struct objlayout_io_state ol_state;
-
-       struct objio_segment *layout;
-
-       struct kref kref;
-       objio_done_fn done;
-       void *private;
-
-       unsigned long length;
-       unsigned numdevs; /* Actually used devs in this IO */
-       /* A per-device variable array of size numdevs */
-       struct _objio_per_comp {
-               struct bio *bio;
-               struct osd_request *or;
-               unsigned long length;
-               u64 offset;
-               unsigned dev;
-       } per_dev[];
+       struct objlayout_io_res oir;
+
+       bool sync;
+       /*FIXME: Support for extra_bytes at ore_get_rw_state() */
+       struct ore_io_state *ios;
 };
 
 /* Send and wait for a get_device_info of devices in the layout,
    then look them up with the osd_initiator library */
-static struct objio_dev_ent *_device_lookup(struct pnfs_layout_hdr *pnfslay,
-                               struct objio_segment *objio_seg, unsigned comp,
-                               gfp_t gfp_flags)
+static int objio_devices_lookup(struct pnfs_layout_hdr *pnfslay,
+       struct objio_segment *objio_seg, unsigned c, struct nfs4_deviceid *d_id,
+       gfp_t gfp_flags)
 {
        struct pnfs_osd_deviceaddr *deviceaddr;
-       struct nfs4_deviceid *d_id;
        struct objio_dev_ent *ode;
        struct osd_dev *od;
        struct osd_dev_info odi;
        int err;
 
-       d_id = &objio_seg->comps[comp].oc_object_id.oid_device_id;
-
        ode = _dev_list_find(NFS_SERVER(pnfslay->plh_inode), d_id);
-       if (ode)
-               return ode;
+       if (ode) {
+               objio_seg->oc.ods[c] = &ode->od; /* must use container_of */
+               return 0;
+       }
 
        err = objlayout_get_deviceinfo(pnfslay, d_id, &deviceaddr, gfp_flags);
        if (unlikely(err)) {
                dprintk("%s: objlayout_get_deviceinfo dev(%llx:%llx) =>%d\n",
                        __func__, _DEVID_LO(d_id), _DEVID_HI(d_id), err);
-               return ERR_PTR(err);
+               return err;
        }
 
        odi.systemid_len = deviceaddr->oda_systemid.len;
        if (odi.systemid_len > sizeof(odi.systemid)) {
+               dprintk("%s: odi.systemid_len > sizeof(systemid=%zd)\n",
+                       __func__, sizeof(odi.systemid));
                err = -EINVAL;
                goto out;
        } else if (odi.systemid_len)
@@ -218,96 +180,53 @@ static struct objio_dev_ent *_device_lookup(struct pnfs_layout_hdr *pnfslay,
 
        ode = _dev_list_add(NFS_SERVER(pnfslay->plh_inode), d_id, od,
                            gfp_flags);
-
+       objio_seg->oc.ods[c] = &ode->od; /* must use container_of */
+       dprintk("Adding new dev_id(%llx:%llx)\n",
+               _DEVID_LO(d_id), _DEVID_HI(d_id));
 out:
-       dprintk("%s: return=%d\n", __func__, err);
        objlayout_put_deviceinfo(deviceaddr);
-       return err ? ERR_PTR(err) : ode;
+       return err;
 }
 
-static int objio_devices_lookup(struct pnfs_layout_hdr *pnfslay,
-       struct objio_segment *objio_seg,
-       gfp_t gfp_flags)
+static void copy_single_comp(struct ore_components *oc, unsigned c,
+                            struct pnfs_osd_object_cred *src_comp)
 {
-       unsigned i;
-       int err;
+       struct ore_comp *ocomp = &oc->comps[c];
 
-       /* lookup all devices */
-       for (i = 0; i < objio_seg->num_comps; i++) {
-               struct objio_dev_ent *ode;
+       WARN_ON(src_comp->oc_cap_key.cred_len > 0); /* libosd is NO_SEC only */
+       WARN_ON(src_comp->oc_cap.cred_len > sizeof(ocomp->cred));
 
-               ode = _device_lookup(pnfslay, objio_seg, i, gfp_flags);
-               if (unlikely(IS_ERR(ode))) {
-                       err = PTR_ERR(ode);
-                       goto out;
-               }
-               objio_seg->ods[i] = ode;
-       }
-       err = 0;
+       ocomp->obj.partition = src_comp->oc_object_id.oid_partition_id;
+       ocomp->obj.id = src_comp->oc_object_id.oid_object_id;
 
-out:
-       dprintk("%s: return=%d\n", __func__, err);
-       return err;
+       memcpy(ocomp->cred, src_comp->oc_cap.cred, sizeof(ocomp->cred));
 }
 
-static int _verify_data_map(struct pnfs_osd_layout *layout)
+int __alloc_objio_seg(unsigned numdevs, gfp_t gfp_flags,
+                      struct objio_segment **pseg)
 {
-       struct pnfs_osd_data_map *data_map = &layout->olo_map;
-       u64 stripe_length;
-       u32 group_width;
-
-/* FIXME: Only raid0 for now. if not go through MDS */
-       if (data_map->odm_raid_algorithm != PNFS_OSD_RAID_0) {
-               printk(KERN_ERR "Only RAID_0 for now\n");
-               return -ENOTSUPP;
-       }
-       if (0 != (data_map->odm_num_comps % (data_map->odm_mirror_cnt + 1))) {
-               printk(KERN_ERR "Data Map wrong, num_comps=%u mirrors=%u\n",
-                         data_map->odm_num_comps, data_map->odm_mirror_cnt);
-               return -EINVAL;
-       }
+       struct __alloc_objio_segment {
+               struct objio_segment olseg;
+               struct ore_dev *ods[numdevs];
+               struct ore_comp comps[numdevs];
+       } *aolseg;
 
-       if (data_map->odm_group_width)
-               group_width = data_map->odm_group_width;
-       else
-               group_width = data_map->odm_num_comps /
-                                               (data_map->odm_mirror_cnt + 1);
-
-       stripe_length = (u64)data_map->odm_stripe_unit * group_width;
-       if (stripe_length >= (1ULL << 32)) {
-               printk(KERN_ERR "Total Stripe length(0x%llx)"
-                         " >= 32bit is not supported\n", _LLU(stripe_length));
-               return -ENOTSUPP;
+       aolseg = kzalloc(sizeof(*aolseg), gfp_flags);
+       if (unlikely(!aolseg)) {
+               dprintk("%s: Faild allocation numdevs=%d size=%zd\n", __func__,
+                       numdevs, sizeof(*aolseg));
+               return -ENOMEM;
        }
 
-       if (0 != (data_map->odm_stripe_unit & ~PAGE_MASK)) {
-               printk(KERN_ERR "Stripe Unit(0x%llx)"
-                         " must be Multples of PAGE_SIZE(0x%lx)\n",
-                         _LLU(data_map->odm_stripe_unit), PAGE_SIZE);
-               return -ENOTSUPP;
-       }
+       aolseg->olseg.oc.numdevs = numdevs;
+       aolseg->olseg.oc.single_comp = EC_MULTPLE_COMPS;
+       aolseg->olseg.oc.comps = aolseg->comps;
+       aolseg->olseg.oc.ods = aolseg->ods;
 
+       *pseg = &aolseg->olseg;
        return 0;
 }
 
-static void copy_single_comp(struct pnfs_osd_object_cred *cur_comp,
-                            struct pnfs_osd_object_cred *src_comp,
-                            struct caps_buffers *caps_p)
-{
-       WARN_ON(src_comp->oc_cap_key.cred_len > sizeof(caps_p->caps_key));
-       WARN_ON(src_comp->oc_cap.cred_len > sizeof(caps_p->creds));
-
-       *cur_comp = *src_comp;
-
-       memcpy(caps_p->caps_key, src_comp->oc_cap_key.cred,
-              sizeof(caps_p->caps_key));
-       cur_comp->oc_cap_key.cred = caps_p->caps_key;
-
-       memcpy(caps_p->creds, src_comp->oc_cap.cred,
-              sizeof(caps_p->creds));
-       cur_comp->oc_cap.cred = caps_p->creds;
-}
-
 int objio_alloc_lseg(struct pnfs_layout_segment **outp,
        struct pnfs_layout_hdr *pnfslay,
        struct pnfs_layout_range *range,
@@ -317,59 +236,43 @@ int objio_alloc_lseg(struct pnfs_layout_segment **outp,
        struct objio_segment *objio_seg;
        struct pnfs_osd_xdr_decode_layout_iter iter;
        struct pnfs_osd_layout layout;
-       struct pnfs_osd_object_cred *cur_comp, src_comp;
-       struct caps_buffers *caps_p;
+       struct pnfs_osd_object_cred src_comp;
+       unsigned cur_comp;
        int err;
 
        err = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr);
        if (unlikely(err))
                return err;
 
-       err = _verify_data_map(&layout);
+       err = __alloc_objio_seg(layout.olo_num_comps, gfp_flags, &objio_seg);
        if (unlikely(err))
                return err;
 
-       objio_seg = kzalloc(sizeof(*objio_seg) +
-                           sizeof(objio_seg->ods[0]) * layout.olo_num_comps +
-                           sizeof(*objio_seg->comps) * layout.olo_num_comps +
-                           sizeof(struct caps_buffers) * layout.olo_num_comps,
-                           gfp_flags);
-       if (!objio_seg)
-               return -ENOMEM;
+       objio_seg->layout.stripe_unit = layout.olo_map.odm_stripe_unit;
+       objio_seg->layout.group_width = layout.olo_map.odm_group_width;
+       objio_seg->layout.group_depth = layout.olo_map.odm_group_depth;
+       objio_seg->layout.mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1;
+       objio_seg->layout.raid_algorithm = layout.olo_map.odm_raid_algorithm;
 
-       objio_seg->comps = (void *)(objio_seg->ods + layout.olo_num_comps);
-       cur_comp = objio_seg->comps;
-       caps_p = (void *)(cur_comp + layout.olo_num_comps);
-       while (pnfs_osd_xdr_decode_layout_comp(&src_comp, &iter, xdr, &err))
-               copy_single_comp(cur_comp++, &src_comp, caps_p++);
+       err = ore_verify_layout(layout.olo_map.odm_num_comps,
+                                         &objio_seg->layout);
        if (unlikely(err))
                goto err;
 
-       objio_seg->num_comps = layout.olo_num_comps;
-       objio_seg->comps_index = layout.olo_comps_index;
-       err = objio_devices_lookup(pnfslay, objio_seg, gfp_flags);
-       if (err)
-               goto err;
-
-       objio_seg->mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1;
-       objio_seg->stripe_unit = layout.olo_map.odm_stripe_unit;
-       if (layout.olo_map.odm_group_width) {
-               objio_seg->group_width = layout.olo_map.odm_group_width;
-               objio_seg->group_depth = layout.olo_map.odm_group_depth;
-               objio_seg->group_count = layout.olo_map.odm_num_comps /
-                                               objio_seg->mirrors_p1 /
-                                               objio_seg->group_width;
-       } else {
-               objio_seg->group_width = layout.olo_map.odm_num_comps /
-                                               objio_seg->mirrors_p1;
-               objio_seg->group_depth = -1;
-               objio_seg->group_count = 1;
+       objio_seg->oc.first_dev = layout.olo_comps_index;
+       cur_comp = 0;
+       while (pnfs_osd_xdr_decode_layout_comp(&src_comp, &iter, xdr, &err)) {
+               copy_single_comp(&objio_seg->oc, cur_comp, &src_comp);
+               err = objio_devices_lookup(pnfslay, objio_seg, cur_comp,
+                                          &src_comp.oc_object_id.oid_device_id,
+                                          gfp_flags);
+               if (err)
+                       goto err;
+               ++cur_comp;
        }
-
-       /* Cache this calculation it will hit for every page */
-       objio_seg->max_io_size = (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE -
-                                 objio_seg->stripe_unit) *
-                                objio_seg->group_width;
+       /* pnfs_osd_xdr_decode_layout_comp returns false on error */
+       if (unlikely(err))
+               goto err;
 
        *outp = &objio_seg->lseg;
        return 0;
@@ -386,43 +289,63 @@ void objio_free_lseg(struct pnfs_layout_segment *lseg)
        int i;
        struct objio_segment *objio_seg = OBJIO_LSEG(lseg);
 
-       for (i = 0; i < objio_seg->num_comps; i++) {
-               if (!objio_seg->ods[i])
+       for (i = 0; i < objio_seg->oc.numdevs; i++) {
+               struct ore_dev *od = objio_seg->oc.ods[i];
+               struct objio_dev_ent *ode;
+
+               if (!od)
                        break;
-               nfs4_put_deviceid_node(&objio_seg->ods[i]->id_node);
+               ode = container_of(od, typeof(*ode), od);
+               nfs4_put_deviceid_node(&ode->id_node);
        }
        kfree(objio_seg);
 }
 
-int objio_alloc_io_state(struct pnfs_layout_segment *lseg,
-                        struct objlayout_io_state **outp,
-                        gfp_t gfp_flags)
+static int
+objio_alloc_io_state(struct pnfs_layout_hdr *pnfs_layout_type, bool is_reading,
+       struct pnfs_layout_segment *lseg, struct page **pages, unsigned pgbase,
+       loff_t offset, size_t count, void *rpcdata, gfp_t gfp_flags,
+       struct objio_state **outp)
 {
        struct objio_segment *objio_seg = OBJIO_LSEG(lseg);
-       struct objio_state *ios;
-       const unsigned first_size = sizeof(*ios) +
-                               objio_seg->num_comps * sizeof(ios->per_dev[0]);
-       const unsigned sec_size = objio_seg->num_comps *
-                                               sizeof(ios->ol_state.ioerrs[0]);
-
-       ios = kzalloc(first_size + sec_size, gfp_flags);
-       if (unlikely(!ios))
+       struct ore_io_state *ios;
+       int ret;
+       struct __alloc_objio_state {
+               struct objio_state objios;
+               struct pnfs_osd_ioerr ioerrs[objio_seg->oc.numdevs];
+       } *aos;
+
+       aos = kzalloc(sizeof(*aos), gfp_flags);
+       if (unlikely(!aos))
                return -ENOMEM;
 
-       ios->layout = objio_seg;
-       ios->ol_state.ioerrs = ((void *)ios) + first_size;
-       ios->ol_state.num_comps = objio_seg->num_comps;
+       objlayout_init_ioerrs(&aos->objios.oir, objio_seg->oc.numdevs,
+                       aos->ioerrs, rpcdata, pnfs_layout_type);
 
-       *outp = &ios->ol_state;
+       ret = ore_get_rw_state(&objio_seg->layout, &objio_seg->oc, is_reading,
+                              offset, count, &ios);
+       if (unlikely(ret)) {
+               kfree(aos);
+               return ret;
+       }
+
+       ios->pages = pages;
+       ios->pgbase = pgbase;
+       ios->private = aos;
+       BUG_ON(ios->nr_pages > (pgbase + count + PAGE_SIZE - 1) >> PAGE_SHIFT);
+
+       aos->objios.sync = 0;
+       aos->objios.ios = ios;
+       *outp = &aos->objios;
        return 0;
 }
 
-void objio_free_io_state(struct objlayout_io_state *ol_state)
+void objio_free_result(struct objlayout_io_res *oir)
 {
-       struct objio_state *ios = container_of(ol_state, struct objio_state,
-                                              ol_state);
+       struct objio_state *objios = container_of(oir, struct objio_state, oir);
 
-       kfree(ios);
+       ore_put_io_state(objios->ios);
+       kfree(objios);
 }
 
 enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep)
@@ -455,539 +378,152 @@ enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep)
        }
 }
 
-static void _clear_bio(struct bio *bio)
+static void __on_dev_error(struct ore_io_state *ios,
+       struct ore_dev *od, unsigned dev_index, enum osd_err_priority oep,
+       u64 dev_offset, u64  dev_len)
 {
-       struct bio_vec *bv;
-       unsigned i;
-
-       __bio_for_each_segment(bv, bio, i, 0) {
-               unsigned this_count = bv->bv_len;
-
-               if (likely(PAGE_SIZE == this_count))
-                       clear_highpage(bv->bv_page);
-               else
-                       zero_user(bv->bv_page, bv->bv_offset, this_count);
-       }
-}
-
-static int _io_check(struct objio_state *ios, bool is_write)
-{
-       enum osd_err_priority oep = OSD_ERR_PRI_NO_ERROR;
-       int lin_ret = 0;
-       int i;
-
-       for (i = 0; i <  ios->numdevs; i++) {
-               struct osd_sense_info osi;
-               struct osd_request *or = ios->per_dev[i].or;
-               int ret;
-
-               if (!or)
-                       continue;
+       struct objio_state *objios = ios->private;
+       struct pnfs_osd_objid pooid;
+       struct objio_dev_ent *ode = container_of(od, typeof(*ode), od);
+       /* FIXME: what to do with more-then-one-group layouts. We need to
+        * translate from ore_io_state index to oc->comps index
+        */
+       unsigned comp = dev_index;
 
-               ret = osd_req_decode_sense(or, &osi);
-               if (likely(!ret))
-                       continue;
+       pooid.oid_device_id = ode->id_node.deviceid;
+       pooid.oid_partition_id = ios->oc->comps[comp].obj.partition;
+       pooid.oid_object_id = ios->oc->comps[comp].obj.id;
 
-               if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) {
-                       /* start read offset passed endof file */
-                       BUG_ON(is_write);
-                       _clear_bio(ios->per_dev[i].bio);
-                       dprintk("%s: start read offset passed end of file "
-                               "offset=0x%llx, length=0x%lx\n", __func__,
-                               _LLU(ios->per_dev[i].offset),
-                               ios->per_dev[i].length);
-
-                       continue; /* we recovered */
-               }
-               objlayout_io_set_result(&ios->ol_state, i,
-                                       &ios->layout->comps[i].oc_object_id,
-                                       osd_pri_2_pnfs_err(osi.osd_err_pri),
-                                       ios->per_dev[i].offset,
-                                       ios->per_dev[i].length,
-                                       is_write);
-
-               if (osi.osd_err_pri >= oep) {
-                       oep = osi.osd_err_pri;
-                       lin_ret = ret;
-               }
-       }
-
-       return lin_ret;
-}
-
-/*
- * Common IO state helpers.
- */
-static void _io_free(struct objio_state *ios)
-{
-       unsigned i;
-
-       for (i = 0; i < ios->numdevs; i++) {
-               struct _objio_per_comp *per_dev = &ios->per_dev[i];
-
-               if (per_dev->or) {
-                       osd_end_request(per_dev->or);
-                       per_dev->or = NULL;
-               }
-
-               if (per_dev->bio) {
-                       bio_put(per_dev->bio);
-                       per_dev->bio = NULL;
-               }
-       }
-}
-
-struct osd_dev *_io_od(struct objio_state *ios, unsigned dev)
-{
-       unsigned min_dev = ios->layout->comps_index;
-       unsigned max_dev = min_dev + ios->layout->num_comps;
-
-       BUG_ON(dev < min_dev || max_dev <= dev);
-       return ios->layout->ods[dev - min_dev]->od;
-}
-
-struct _striping_info {
-       u64 obj_offset;
-       u64 group_length;
-       unsigned dev;
-       unsigned unit_off;
-};
-
-static void _calc_stripe_info(struct objio_state *ios, u64 file_offset,
-                             struct _striping_info *si)
-{
-       u32     stripe_unit = ios->layout->stripe_unit;
-       u32     group_width = ios->layout->group_width;
-       u64     group_depth = ios->layout->group_depth;
-       u32     U = stripe_unit * group_width;
-
-       u64     T = U * group_depth;
-       u64     S = T * ios->layout->group_count;
-       u64     M = div64_u64(file_offset, S);
-
-       /*
-       G = (L - (M * S)) / T
-       H = (L - (M * S)) % T
-       */
-       u64     LmodU = file_offset - M * S;
-       u32     G = div64_u64(LmodU, T);
-       u64     H = LmodU - G * T;
-
-       u32     N = div_u64(H, U);
-
-       div_u64_rem(file_offset, stripe_unit, &si->unit_off);
-       si->obj_offset = si->unit_off + (N * stripe_unit) +
-                                 (M * group_depth * stripe_unit);
-
-       /* "H - (N * U)" is just "H % U" so it's bound to u32 */
-       si->dev = (u32)(H - (N * U)) / stripe_unit + G * group_width;
-       si->dev *= ios->layout->mirrors_p1;
-
-       si->group_length = T - H;
-}
-
-static int _add_stripe_unit(struct objio_state *ios,  unsigned *cur_pg,
-               unsigned pgbase, struct _objio_per_comp *per_dev, int len,
-               gfp_t gfp_flags)
-{
-       unsigned pg = *cur_pg;
-       int cur_len = len;
-       struct request_queue *q =
-                       osd_request_queue(_io_od(ios, per_dev->dev));
-
-       if (per_dev->bio == NULL) {
-               unsigned pages_in_stripe = ios->layout->group_width *
-                                     (ios->layout->stripe_unit / PAGE_SIZE);
-               unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) /
-                                   ios->layout->group_width;
-
-               if (BIO_MAX_PAGES_KMALLOC < bio_size)
-                       bio_size = BIO_MAX_PAGES_KMALLOC;
-
-               per_dev->bio = bio_kmalloc(gfp_flags, bio_size);
-               if (unlikely(!per_dev->bio)) {
-                       dprintk("Faild to allocate BIO size=%u\n", bio_size);
-                       return -ENOMEM;
-               }
-       }
-
-       while (cur_len > 0) {
-               unsigned pglen = min_t(unsigned, PAGE_SIZE - pgbase, cur_len);
-               unsigned added_len;
-
-               BUG_ON(ios->ol_state.nr_pages <= pg);
-               cur_len -= pglen;
-
-               added_len = bio_add_pc_page(q, per_dev->bio,
-                                       ios->ol_state.pages[pg], pglen, pgbase);
-               if (unlikely(pglen != added_len))
-                       return -ENOMEM;
-               pgbase = 0;
-               ++pg;
-       }
-       BUG_ON(cur_len);
-
-       per_dev->length += len;
-       *cur_pg = pg;
-       return 0;
-}
-
-static int _prepare_one_group(struct objio_state *ios, u64 length,
-                             struct _striping_info *si, unsigned *last_pg,
-                             gfp_t gfp_flags)
-{
-       unsigned stripe_unit = ios->layout->stripe_unit;
-       unsigned mirrors_p1 = ios->layout->mirrors_p1;
-       unsigned devs_in_group = ios->layout->group_width * mirrors_p1;
-       unsigned dev = si->dev;
-       unsigned first_dev = dev - (dev % devs_in_group);
-       unsigned max_comp = ios->numdevs ? ios->numdevs - mirrors_p1 : 0;
-       unsigned cur_pg = *last_pg;
-       int ret = 0;
-
-       while (length) {
-               struct _objio_per_comp *per_dev = &ios->per_dev[dev - first_dev];
-               unsigned cur_len, page_off = 0;
-
-               if (!per_dev->length) {
-                       per_dev->dev = dev;
-                       if (dev < si->dev) {
-                               per_dev->offset = si->obj_offset + stripe_unit -
-                                                                  si->unit_off;
-                               cur_len = stripe_unit;
-                       } else if (dev == si->dev) {
-                               per_dev->offset = si->obj_offset;
-                               cur_len = stripe_unit - si->unit_off;
-                               page_off = si->unit_off & ~PAGE_MASK;
-                               BUG_ON(page_off &&
-                                     (page_off != ios->ol_state.pgbase));
-                       } else { /* dev > si->dev */
-                               per_dev->offset = si->obj_offset - si->unit_off;
-                               cur_len = stripe_unit;
-                       }
-
-                       if (max_comp < dev - first_dev)
-                               max_comp = dev - first_dev;
-               } else {
-                       cur_len = stripe_unit;
-               }
-               if (cur_len >= length)
-                       cur_len = length;
-
-               ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev,
-                                      cur_len, gfp_flags);
-               if (unlikely(ret))
-                       goto out;
-
-               dev += mirrors_p1;
-               dev = (dev % devs_in_group) + first_dev;
-
-               length -= cur_len;
-               ios->length += cur_len;
-       }
-out:
-       ios->numdevs = max_comp + mirrors_p1;
-       *last_pg = cur_pg;
-       return ret;
-}
-
-static int _io_rw_pagelist(struct objio_state *ios, gfp_t gfp_flags)
-{
-       u64 length = ios->ol_state.count;
-       u64 offset = ios->ol_state.offset;
-       struct _striping_info si;
-       unsigned last_pg = 0;
-       int ret = 0;
-
-       while (length) {
-               _calc_stripe_info(ios, offset, &si);
-
-               if (length < si.group_length)
-                       si.group_length = length;
-
-               ret = _prepare_one_group(ios, si.group_length, &si, &last_pg, gfp_flags);
-               if (unlikely(ret))
-                       goto out;
-
-               offset += si.group_length;
-               length -= si.group_length;
-       }
-
-out:
-       if (!ios->length)
-               return ret;
-
-       return 0;
-}
-
-static ssize_t _sync_done(struct objio_state *ios)
-{
-       struct completion *waiting = ios->private;
-
-       complete(waiting);
-       return 0;
-}
-
-static void _last_io(struct kref *kref)
-{
-       struct objio_state *ios = container_of(kref, struct objio_state, kref);
-
-       ios->done(ios);
-}
-
-static void _done_io(struct osd_request *or, void *p)
-{
-       struct objio_state *ios = p;
-
-       kref_put(&ios->kref, _last_io);
-}
-
-static ssize_t _io_exec(struct objio_state *ios)
-{
-       DECLARE_COMPLETION_ONSTACK(wait);
-       ssize_t status = 0; /* sync status */
-       unsigned i;
-       objio_done_fn saved_done_fn = ios->done;
-       bool sync = ios->ol_state.sync;
-
-       if (sync) {
-               ios->done = _sync_done;
-               ios->private = &wait;
-       }
-
-       kref_init(&ios->kref);
-
-       for (i = 0; i < ios->numdevs; i++) {
-               struct osd_request *or = ios->per_dev[i].or;
-
-               if (!or)
-                       continue;
-
-               kref_get(&ios->kref);
-               osd_execute_request_async(or, _done_io, ios);
-       }
-
-       kref_put(&ios->kref, _last_io);
-
-       if (sync) {
-               wait_for_completion(&wait);
-               status = saved_done_fn(ios);
-       }
-
-       return status;
+       objlayout_io_set_result(&objios->oir, comp,
+                               &pooid, osd_pri_2_pnfs_err(oep),
+                               dev_offset, dev_len, !ios->reading);
 }
 
 /*
  * read
  */
-static ssize_t _read_done(struct objio_state *ios)
+static void _read_done(struct ore_io_state *ios, void *private)
 {
+       struct objio_state *objios = private;
        ssize_t status;
-       int ret = _io_check(ios, false);
+       int ret = ore_check_io(ios, &__on_dev_error);
 
-       _io_free(ios);
+       /* FIXME: _io_free(ios) can we dealocate the libosd resources; */
 
        if (likely(!ret))
                status = ios->length;
        else
                status = ret;
 
-       objlayout_read_done(&ios->ol_state, status, ios->ol_state.sync);
-       return status;
+       objlayout_read_done(&objios->oir, status, objios->sync);
 }
 
-static int _read_mirrors(struct objio_state *ios, unsigned cur_comp)
+int objio_read_pagelist(struct nfs_read_data *rdata)
 {
-       struct osd_request *or = NULL;
-       struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp];
-       unsigned dev = per_dev->dev;
-       struct pnfs_osd_object_cred *cred =
-                       &ios->layout->comps[cur_comp];
-       struct osd_obj_id obj = {
-               .partition = cred->oc_object_id.oid_partition_id,
-               .id = cred->oc_object_id.oid_object_id,
-       };
+       struct objio_state *objios;
        int ret;
 
-       or = osd_start_request(_io_od(ios, dev), GFP_KERNEL);
-       if (unlikely(!or)) {
-               ret = -ENOMEM;
-               goto err;
-       }
-       per_dev->or = or;
-
-       osd_req_read(or, &obj, per_dev->offset, per_dev->bio, per_dev->length);
-
-       ret = osd_finalize_request(or, 0, cred->oc_cap.cred, NULL);
-       if (ret) {
-               dprintk("%s: Faild to osd_finalize_request() => %d\n",
-                       __func__, ret);
-               goto err;
-       }
-
-       dprintk("%s:[%d] dev=%d obj=0x%llx start=0x%llx length=0x%lx\n",
-               __func__, cur_comp, dev, obj.id, _LLU(per_dev->offset),
-               per_dev->length);
-
-err:
-       return ret;
-}
-
-static ssize_t _read_exec(struct objio_state *ios)
-{
-       unsigned i;
-       int ret;
-
-       for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) {
-               if (!ios->per_dev[i].length)
-                       continue;
-               ret = _read_mirrors(ios, i);
-               if (unlikely(ret))
-                       goto err;
-       }
-
-       ios->done = _read_done;
-       return _io_exec(ios); /* In sync mode exec returns the io status */
-
-err:
-       _io_free(ios);
-       return ret;
-}
-
-ssize_t objio_read_pagelist(struct objlayout_io_state *ol_state)
-{
-       struct objio_state *ios = container_of(ol_state, struct objio_state,
-                                              ol_state);
-       int ret;
-
-       ret = _io_rw_pagelist(ios, GFP_KERNEL);
+       ret = objio_alloc_io_state(NFS_I(rdata->inode)->layout, true,
+                       rdata->lseg, rdata->args.pages, rdata->args.pgbase,
+                       rdata->args.offset, rdata->args.count, rdata,
+                       GFP_KERNEL, &objios);
        if (unlikely(ret))
                return ret;
 
-       return _read_exec(ios);
+       objios->ios->done = _read_done;
+       dprintk("%s: offset=0x%llx length=0x%x\n", __func__,
+               rdata->args.offset, rdata->args.count);
+       return ore_read(objios->ios);
 }
 
 /*
  * write
  */
-static ssize_t _write_done(struct objio_state *ios)
+static void _write_done(struct ore_io_state *ios, void *private)
 {
+       struct objio_state *objios = private;
        ssize_t status;
-       int ret = _io_check(ios, true);
+       int ret = ore_check_io(ios, &__on_dev_error);
 
-       _io_free(ios);
+       /* FIXME: _io_free(ios) can we dealocate the libosd resources; */
 
        if (likely(!ret)) {
                /* FIXME: should be based on the OSD's persistence model
                 * See OSD2r05 Section 4.13 Data persistence model */
-               ios->ol_state.committed = NFS_FILE_SYNC;
+               objios->oir.committed = NFS_FILE_SYNC;
                status = ios->length;
        } else {
                status = ret;
        }
 
-       objlayout_write_done(&ios->ol_state, status, ios->ol_state.sync);
-       return status;
+       objlayout_write_done(&objios->oir, status, objios->sync);
 }
 
-static int _write_mirrors(struct objio_state *ios, unsigned cur_comp)
+static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate)
 {
-       struct _objio_per_comp *master_dev = &ios->per_dev[cur_comp];
-       unsigned dev = ios->per_dev[cur_comp].dev;
-       unsigned last_comp = cur_comp + ios->layout->mirrors_p1;
-       int ret;
-
-       for (; cur_comp < last_comp; ++cur_comp, ++dev) {
-               struct osd_request *or = NULL;
-               struct pnfs_osd_object_cred *cred =
-                                       &ios->layout->comps[cur_comp];
-               struct osd_obj_id obj = {
-                       .partition = cred->oc_object_id.oid_partition_id,
-                       .id = cred->oc_object_id.oid_object_id,
-               };
-               struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp];
-               struct bio *bio;
-
-               or = osd_start_request(_io_od(ios, dev), GFP_NOFS);
-               if (unlikely(!or)) {
-                       ret = -ENOMEM;
-                       goto err;
-               }
-               per_dev->or = or;
-
-               if (per_dev != master_dev) {
-                       bio = bio_kmalloc(GFP_NOFS,
-                                         master_dev->bio->bi_max_vecs);
-                       if (unlikely(!bio)) {
-                               dprintk("Faild to allocate BIO size=%u\n",
-                                       master_dev->bio->bi_max_vecs);
-                               ret = -ENOMEM;
-                               goto err;
-                       }
-
-                       __bio_clone(bio, master_dev->bio);
-                       bio->bi_bdev = NULL;
-                       bio->bi_next = NULL;
-                       per_dev->bio = bio;
-                       per_dev->dev = dev;
-                       per_dev->length = master_dev->length;
-                       per_dev->offset =  master_dev->offset;
-               } else {
-                       bio = master_dev->bio;
-                       bio->bi_rw |= REQ_WRITE;
-               }
-
-               osd_req_write(or, &obj, per_dev->offset, bio, per_dev->length);
+       struct objio_state *objios = priv;
+       struct nfs_write_data *wdata = objios->oir.rpcdata;
+       pgoff_t index = offset / PAGE_SIZE;
+       struct page *page = find_get_page(wdata->inode->i_mapping, index);
 
-               ret = osd_finalize_request(or, 0, cred->oc_cap.cred, NULL);
-               if (ret) {
-                       dprintk("%s: Faild to osd_finalize_request() => %d\n",
-                               __func__, ret);
-                       goto err;
+       if (!page) {
+               page = find_or_create_page(wdata->inode->i_mapping,
+                                               index, GFP_NOFS);
+               if (unlikely(!page)) {
+                       dprintk("%s: grab_cache_page Failed index=0x%lx\n",
+                               __func__, index);
+                       return NULL;
                }
-
-               dprintk("%s:[%d] dev=%d obj=0x%llx start=0x%llx length=0x%lx\n",
-                       __func__, cur_comp, dev, obj.id, _LLU(per_dev->offset),
-                       per_dev->length);
+               unlock_page(page);
        }
+       if (PageDirty(page) || PageWriteback(page))
+               *uptodate = true;
+       else
+               *uptodate = PageUptodate(page);
+       dprintk("%s: index=0x%lx uptodate=%d\n", __func__, index, *uptodate);
+       return page;
+}
 
-err:
-       return ret;
+static void __r4w_put_page(void *priv, struct page *page)
+{
+       dprintk("%s: index=0x%lx\n", __func__, page->index);
+       page_cache_release(page);
+       return;
 }
 
-static ssize_t _write_exec(struct objio_state *ios)
+static const struct _ore_r4w_op _r4w_op = {
+       .get_page = &__r4w_get_page,
+       .put_page = &__r4w_put_page,
+};
+
+int objio_write_pagelist(struct nfs_write_data *wdata, int how)
 {
-       unsigned i;
+       struct objio_state *objios;
        int ret;
 
-       for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) {
-               if (!ios->per_dev[i].length)
-                       continue;
-               ret = _write_mirrors(ios, i);
-               if (unlikely(ret))
-                       goto err;
-       }
-
-       ios->done = _write_done;
-       return _io_exec(ios); /* In sync mode exec returns the io->status */
+       ret = objio_alloc_io_state(NFS_I(wdata->inode)->layout, false,
+                       wdata->lseg, wdata->args.pages, wdata->args.pgbase,
+                       wdata->args.offset, wdata->args.count, wdata, GFP_NOFS,
+                       &objios);
+       if (unlikely(ret))
+               return ret;
 
-err:
-       _io_free(ios);
-       return ret;
-}
+       objios->sync = 0 != (how & FLUSH_SYNC);
+       objios->ios->r4w = &_r4w_op;
 
-ssize_t objio_write_pagelist(struct objlayout_io_state *ol_state, bool stable)
-{
-       struct objio_state *ios = container_of(ol_state, struct objio_state,
-                                              ol_state);
-       int ret;
+       if (!objios->sync)
+               objios->ios->done = _write_done;
 
-       /* TODO: ios->stable = stable; */
-       ret = _io_rw_pagelist(ios, GFP_NOFS);
+       dprintk("%s: offset=0x%llx length=0x%x\n", __func__,
+               wdata->args.offset, wdata->args.count);
+       ret = ore_write(objios->ios);
        if (unlikely(ret))
                return ret;
 
-       return _write_exec(ios);
+       if (objios->sync)
+               _write_done(objios->ios, objios);
+
+       return 0;
 }
 
 static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
@@ -997,7 +533,7 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,
                return false;
 
        return pgio->pg_count + req->wb_bytes <=
-                       OBJIO_LSEG(pgio->pg_lseg)->max_io_size;
+                       OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length;
 }
 
 static const struct nfs_pageio_ops objio_pg_read_ops = {
index 1d06f8e..72074e3 100644 (file)
@@ -156,77 +156,39 @@ last_byte_offset(u64 start, u64 len)
        return end > start ? end - 1 : NFS4_MAX_UINT64;
 }
 
-static struct objlayout_io_state *
-objlayout_alloc_io_state(struct pnfs_layout_hdr *pnfs_layout_type,
-                       struct page **pages,
-                       unsigned pgbase,
-                       loff_t offset,
-                       size_t count,
-                       struct pnfs_layout_segment *lseg,
-                       void *rpcdata,
-                       gfp_t gfp_flags)
+void _fix_verify_io_params(struct pnfs_layout_segment *lseg,
+                          struct page ***p_pages, unsigned *p_pgbase,
+                          u64 offset, unsigned long count)
 {
-       struct objlayout_io_state *state;
        u64 lseg_end_offset;
 
-       dprintk("%s: allocating io_state\n", __func__);
-       if (objio_alloc_io_state(lseg, &state, gfp_flags))
-               return NULL;
-
        BUG_ON(offset < lseg->pls_range.offset);
        lseg_end_offset = end_offset(lseg->pls_range.offset,
                                     lseg->pls_range.length);
        BUG_ON(offset >= lseg_end_offset);
-       if (offset + count > lseg_end_offset) {
-               count = lseg->pls_range.length -
-                               (offset - lseg->pls_range.offset);
-               dprintk("%s: truncated count %Zd\n", __func__, count);
-       }
+       WARN_ON(offset + count > lseg_end_offset);
 
-       if (pgbase > PAGE_SIZE) {
-               pages += pgbase >> PAGE_SHIFT;
-               pgbase &= ~PAGE_MASK;
+       if (*p_pgbase > PAGE_SIZE) {
+               dprintk("%s: pgbase(0x%x) > PAGE_SIZE\n", __func__, *p_pgbase);
+               *p_pages += *p_pgbase >> PAGE_SHIFT;
+               *p_pgbase &= ~PAGE_MASK;
        }
-
-       INIT_LIST_HEAD(&state->err_list);
-       state->lseg = lseg;
-       state->rpcdata = rpcdata;
-       state->pages = pages;
-       state->pgbase = pgbase;
-       state->nr_pages = (pgbase + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       state->offset = offset;
-       state->count = count;
-       state->sync = 0;
-
-       return state;
-}
-
-static void
-objlayout_free_io_state(struct objlayout_io_state *state)
-{
-       dprintk("%s: freeing io_state\n", __func__);
-       if (unlikely(!state))
-               return;
-
-       objio_free_io_state(state);
 }
 
 /*
  * I/O done common code
  */
 static void
-objlayout_iodone(struct objlayout_io_state *state)
+objlayout_iodone(struct objlayout_io_res *oir)
 {
-       dprintk("%s: state %p status\n", __func__, state);
-
-       if (likely(state->status >= 0)) {
-               objlayout_free_io_state(state);
+       if (likely(oir->status >= 0)) {
+               objio_free_result(oir);
        } else {
-               struct objlayout *objlay = OBJLAYOUT(state->lseg->pls_layout);
+               struct objlayout *objlay = oir->objlay;
 
                spin_lock(&objlay->lock);
                objlay->delta_space_valid = OBJ_DSU_INVALID;
-               list_add(&objlay->err_list, &state->err_list);
+               list_add(&objlay->err_list, &oir->err_list);
                spin_unlock(&objlay->lock);
        }
 }
@@ -238,13 +200,13 @@ objlayout_iodone(struct objlayout_io_state *state)
  * the error for later reporting at layout-return.
  */
 void
-objlayout_io_set_result(struct objlayout_io_state *state, unsigned index,
+objlayout_io_set_result(struct objlayout_io_res *oir, unsigned index,
                        struct pnfs_osd_objid *pooid, int osd_error,
                        u64 offset, u64 length, bool is_write)
 {
-       struct pnfs_osd_ioerr *ioerr = &state->ioerrs[index];
+       struct pnfs_osd_ioerr *ioerr = &oir->ioerrs[index];
 
-       BUG_ON(index >= state->num_comps);
+       BUG_ON(index >= oir->num_comps);
        if (osd_error) {
                ioerr->oer_component = *pooid;
                ioerr->oer_comp_offset = offset;
@@ -285,21 +247,18 @@ static void _rpc_read_complete(struct work_struct *work)
 }
 
 void
-objlayout_read_done(struct objlayout_io_state *state, ssize_t status, bool sync)
+objlayout_read_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
 {
-       int eof = state->eof;
-       struct nfs_read_data *rdata;
+       struct nfs_read_data *rdata = oir->rpcdata;
 
-       state->status = status;
-       dprintk("%s: Begin status=%zd eof=%d\n", __func__, status, eof);
-       rdata = state->rpcdata;
-       rdata->task.tk_status = status;
-       if (status >= 0) {
+       oir->status = rdata->task.tk_status = status;
+       if (status >= 0)
                rdata->res.count = status;
-               rdata->res.eof = eof;
-       }
-       objlayout_iodone(state);
-       /* must not use state after this point */
+       objlayout_iodone(oir);
+       /* must not use oir after this point */
+
+       dprintk("%s: Return status=%zd eof=%d sync=%d\n", __func__,
+               status, rdata->res.eof, sync);
 
        if (sync)
                pnfs_ld_read_done(rdata);
@@ -317,40 +276,36 @@ objlayout_read_pagelist(struct nfs_read_data *rdata)
 {
        loff_t offset = rdata->args.offset;
        size_t count = rdata->args.count;
-       struct objlayout_io_state *state;
-       ssize_t status = 0;
+       int err;
        loff_t eof;
 
-       dprintk("%s: Begin inode %p offset %llu count %d\n",
-               __func__, rdata->inode, offset, (int)count);
-
        eof = i_size_read(rdata->inode);
        if (unlikely(offset + count > eof)) {
                if (offset >= eof) {
-                       status = 0;
+                       err = 0;
                        rdata->res.count = 0;
                        rdata->res.eof = 1;
+                       /*FIXME: do we need to call pnfs_ld_read_done() */
                        goto out;
                }
                count = eof - offset;
        }
 
-       state = objlayout_alloc_io_state(NFS_I(rdata->inode)->layout,
-                                        rdata->args.pages, rdata->args.pgbase,
-                                        offset, count,
-                                        rdata->lseg, rdata,
-                                        GFP_KERNEL);
-       if (unlikely(!state)) {
-               status = -ENOMEM;
-               goto out;
-       }
+       rdata->res.eof = (offset + count) >= eof;
+       _fix_verify_io_params(rdata->lseg, &rdata->args.pages,
+                             &rdata->args.pgbase,
+                             rdata->args.offset, rdata->args.count);
 
-       state->eof = state->offset + state->count >= eof;
+       dprintk("%s: inode(%lx) offset 0x%llx count 0x%Zx eof=%d\n",
+               __func__, rdata->inode->i_ino, offset, count, rdata->res.eof);
 
-       status = objio_read_pagelist(state);
+       err = objio_read_pagelist(rdata);
  out:
-       dprintk("%s: Return status %Zd\n", __func__, status);
-       rdata->pnfs_error = status;
+       if (unlikely(err)) {
+               rdata->pnfs_error = err;
+               dprintk("%s: Returned Error %d\n", __func__, err);
+               return PNFS_NOT_ATTEMPTED;
+       }
        return PNFS_ATTEMPTED;
 }
 
@@ -371,26 +326,20 @@ static void _rpc_write_complete(struct work_struct *work)
 }
 
 void
-objlayout_write_done(struct objlayout_io_state *state, ssize_t status,
-                    bool sync)
+objlayout_write_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
 {
-       struct nfs_write_data *wdata;
+       struct nfs_write_data *wdata = oir->rpcdata;
 
-       dprintk("%s: Begin\n", __func__);
-       wdata = state->rpcdata;
-       state->status = status;
-       wdata->task.tk_status = status;
+       oir->status = wdata->task.tk_status = status;
        if (status >= 0) {
                wdata->res.count = status;
-               wdata->verf.committed = state->committed;
-               dprintk("%s: Return status %d committed %d\n",
-                       __func__, wdata->task.tk_status,
-                       wdata->verf.committed);
-       } else
-               dprintk("%s: Return status %d\n",
-                       __func__, wdata->task.tk_status);
-       objlayout_iodone(state);
-       /* must not use state after this point */
+               wdata->verf.committed = oir->committed;
+       }
+       objlayout_iodone(oir);
+       /* must not use oir after this point */
+
+       dprintk("%s: Return status %zd committed %d sync=%d\n", __func__,
+               status, wdata->verf.committed, sync);
 
        if (sync)
                pnfs_ld_write_done(wdata);
@@ -407,30 +356,18 @@ enum pnfs_try_status
 objlayout_write_pagelist(struct nfs_write_data *wdata,
                         int how)
 {
-       struct objlayout_io_state *state;
-       ssize_t status;
-
-       dprintk("%s: Begin inode %p offset %llu count %u\n",
-               __func__, wdata->inode, wdata->args.offset, wdata->args.count);
-
-       state = objlayout_alloc_io_state(NFS_I(wdata->inode)->layout,
-                                        wdata->args.pages,
-                                        wdata->args.pgbase,
-                                        wdata->args.offset,
-                                        wdata->args.count,
-                                        wdata->lseg, wdata,
-                                        GFP_NOFS);
-       if (unlikely(!state)) {
-               status = -ENOMEM;
-               goto out;
-       }
+       int err;
 
-       state->sync = how & FLUSH_SYNC;
+       _fix_verify_io_params(wdata->lseg, &wdata->args.pages,
+                             &wdata->args.pgbase,
+                             wdata->args.offset, wdata->args.count);
 
-       status = objio_write_pagelist(state, how & FLUSH_STABLE);
- out:
-       dprintk("%s: Return status %Zd\n", __func__, status);
-       wdata->pnfs_error = status;
+       err = objio_write_pagelist(wdata, how);
+       if (unlikely(err)) {
+               wdata->pnfs_error = err;
+               dprintk("%s: Returned Error %d\n", __func__, err);
+               return PNFS_NOT_ATTEMPTED;
+       }
        return PNFS_ATTEMPTED;
 }
 
@@ -537,14 +474,14 @@ merge_ioerr(struct pnfs_osd_ioerr *dest_err,
 static void
 encode_accumulated_error(struct objlayout *objlay, __be32 *p)
 {
-       struct objlayout_io_state *state, *tmp;
+       struct objlayout_io_res *oir, *tmp;
        struct pnfs_osd_ioerr accumulated_err = {.oer_errno = 0};
 
-       list_for_each_entry_safe(state, tmp, &objlay->err_list, err_list) {
+       list_for_each_entry_safe(oir, tmp, &objlay->err_list, err_list) {
                unsigned i;
 
-               for (i = 0; i < state->num_comps; i++) {
-                       struct pnfs_osd_ioerr *ioerr = &state->ioerrs[i];
+               for (i = 0; i < oir->num_comps; i++) {
+                       struct pnfs_osd_ioerr *ioerr = &oir->ioerrs[i];
 
                        if (!ioerr->oer_errno)
                                continue;
@@ -563,8 +500,8 @@ encode_accumulated_error(struct objlayout *objlay, __be32 *p)
 
                        merge_ioerr(&accumulated_err, ioerr);
                }
-               list_del(&state->err_list);
-               objlayout_free_io_state(state);
+               list_del(&oir->err_list);
+               objio_free_result(oir);
        }
 
        pnfs_osd_xdr_encode_ioerr(p, &accumulated_err);
@@ -576,7 +513,7 @@ objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay,
                              const struct nfs4_layoutreturn_args *args)
 {
        struct objlayout *objlay = OBJLAYOUT(pnfslay);
-       struct objlayout_io_state *state, *tmp;
+       struct objlayout_io_res *oir, *tmp;
        __be32 *start;
 
        dprintk("%s: Begin\n", __func__);
@@ -585,13 +522,13 @@ objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay,
 
        spin_lock(&objlay->lock);
 
-       list_for_each_entry_safe(state, tmp, &objlay->err_list, err_list) {
+       list_for_each_entry_safe(oir, tmp, &objlay->err_list, err_list) {
                __be32 *last_xdr = NULL, *p;
                unsigned i;
                int res = 0;
 
-               for (i = 0; i < state->num_comps; i++) {
-                       struct pnfs_osd_ioerr *ioerr = &state->ioerrs[i];
+               for (i = 0; i < oir->num_comps; i++) {
+                       struct pnfs_osd_ioerr *ioerr = &oir->ioerrs[i];
 
                        if (!ioerr->oer_errno)
                                continue;
@@ -615,7 +552,7 @@ objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay,
                        }
 
                        last_xdr = p;
-                       pnfs_osd_xdr_encode_ioerr(p, &state->ioerrs[i]);
+                       pnfs_osd_xdr_encode_ioerr(p, &oir->ioerrs[i]);
                }
 
                /* TODO: use xdr_write_pages */
@@ -631,8 +568,8 @@ objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay,
                        encode_accumulated_error(objlay, last_xdr);
                        goto loop_done;
                }
-               list_del(&state->err_list);
-               objlayout_free_io_state(state);
+               list_del(&oir->err_list);
+               objio_free_result(oir);
        }
 loop_done:
        spin_unlock(&objlay->lock);
index a8244c8..8ec3472 100644 (file)
@@ -74,19 +74,11 @@ OBJLAYOUT(struct pnfs_layout_hdr *lo)
  * per-I/O operation state
  * embedded in objects provider io_state data structure
  */
-struct objlayout_io_state {
-       struct pnfs_layout_segment *lseg;
-
-       struct page **pages;
-       unsigned pgbase;
-       unsigned nr_pages;
-       unsigned long count;
-       loff_t offset;
-       bool sync;
+struct objlayout_io_res {
+       struct objlayout *objlay;
 
        void *rpcdata;
        int status;             /* res */
-       int eof;                /* res */
        int committed;          /* res */
 
        /* Error reporting (layout_return) */
@@ -100,6 +92,18 @@ struct objlayout_io_state {
        struct pnfs_osd_ioerr *ioerrs;
 };
 
+static inline
+void objlayout_init_ioerrs(struct objlayout_io_res *oir, unsigned num_comps,
+                       struct pnfs_osd_ioerr *ioerrs, void *rpcdata,
+                       struct pnfs_layout_hdr *pnfs_layout_type)
+{
+       oir->objlay = OBJLAYOUT(pnfs_layout_type);
+       oir->rpcdata = rpcdata;
+       INIT_LIST_HEAD(&oir->err_list);
+       oir->num_comps = num_comps;
+       oir->ioerrs = ioerrs;
+}
+
 /*
  * Raid engine I/O API
  */
@@ -110,28 +114,24 @@ extern int objio_alloc_lseg(struct pnfs_layout_segment **outp,
        gfp_t gfp_flags);
 extern void objio_free_lseg(struct pnfs_layout_segment *lseg);
 
-extern int objio_alloc_io_state(
-       struct pnfs_layout_segment *lseg,
-       struct objlayout_io_state **outp,
-       gfp_t gfp_flags);
-extern void objio_free_io_state(struct objlayout_io_state *state);
+/* objio_free_result will free these @oir structs recieved from
+ * objlayout_{read,write}_done
+ */
+extern void objio_free_result(struct objlayout_io_res *oir);
 
-extern ssize_t objio_read_pagelist(struct objlayout_io_state *ol_state);
-extern ssize_t objio_write_pagelist(struct objlayout_io_state *ol_state,
-                                   bool stable);
+extern int objio_read_pagelist(struct nfs_read_data *rdata);
+extern int objio_write_pagelist(struct nfs_write_data *wdata, int how);
 
 /*
  * callback API
  */
-extern void objlayout_io_set_result(struct objlayout_io_state *state,
+extern void objlayout_io_set_result(struct objlayout_io_res *oir,
                        unsigned index, struct pnfs_osd_objid *pooid,
                        int osd_error, u64 offset, u64 length, bool is_write);
 
 static inline void
-objlayout_add_delta_space_used(struct objlayout_io_state *state, s64 space_used)
+objlayout_add_delta_space_used(struct objlayout *objlay, s64 space_used)
 {
-       struct objlayout *objlay = OBJLAYOUT(state->lseg->pls_layout);
-
        /* If one of the I/Os errored out and the delta_space_used was
         * invalid we render the complete report as invalid. Protocol mandate
         * the DSU be accurate or not reported.
@@ -144,9 +144,9 @@ objlayout_add_delta_space_used(struct objlayout_io_state *state, s64 space_used)
        spin_unlock(&objlay->lock);
 }
 
-extern void objlayout_read_done(struct objlayout_io_state *state,
+extern void objlayout_read_done(struct objlayout_io_res *oir,
                                ssize_t status, bool sync);
-extern void objlayout_write_done(struct objlayout_io_state *state,
+extern void objlayout_write_done(struct objlayout_io_res *oir,
                                 ssize_t status, bool sync);
 
 extern int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
index b60970c..0a5ff5c 100644 (file)
@@ -41,7 +41,7 @@ nfs_page_free(struct nfs_page *p)
 
 /**
  * nfs_create_request - Create an NFS read/write request.
- * @file: file descriptor to use
+ * @ctx: open context to use
  * @inode: inode to which the request is attached
  * @page: page to write
  * @offset: starting offset within the page for the write
index ee73d9a..a2478bc 100644 (file)
@@ -1443,17 +1443,31 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
        /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */
        data = kzalloc(sizeof(*data), GFP_NOFS);
        if (!data) {
-               mark_inode_dirty_sync(inode);
                status = -ENOMEM;
                goto out;
        }
 
+       if (!test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags))
+               goto out_free;
+
+       if (test_and_set_bit(NFS_INO_LAYOUTCOMMITTING, &nfsi->flags)) {
+               if (!sync) {
+                       status = -EAGAIN;
+                       goto out_free;
+               }
+               status = wait_on_bit_lock(&nfsi->flags, NFS_INO_LAYOUTCOMMITTING,
+                                       nfs_wait_bit_killable, TASK_KILLABLE);
+               if (status)
+                       goto out_free;
+       }
+
        INIT_LIST_HEAD(&data->lseg_list);
        spin_lock(&inode->i_lock);
        if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
+               clear_bit(NFS_INO_LAYOUTCOMMITTING, &nfsi->flags);
                spin_unlock(&inode->i_lock);
-               kfree(data);
-               goto out;
+               wake_up_bit(&nfsi->flags, NFS_INO_LAYOUTCOMMITTING);
+               goto out_free;
        }
 
        pnfs_list_write_lseg(inode, &data->lseg_list);
@@ -1475,6 +1489,11 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
 
        status = nfs4_proc_layoutcommit(data, sync);
 out:
+       if (status)
+               mark_inode_dirty_sync(inode);
        dprintk("<-- %s status %d\n", __func__, status);
        return status;
+out_free:
+       kfree(data);
+       goto out;
 }
index 2219c88..b016b8a 100644 (file)
@@ -1243,7 +1243,6 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
 {
        struct nfs_writeargs    *argp = &data->args;
        struct nfs_writeres     *resp = &data->res;
-       struct nfs_server       *server = NFS_SERVER(data->inode);
        int status;
 
        dprintk("NFS: %5u nfs_writeback_done (status %d)\n",
@@ -1277,7 +1276,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
                if (time_before(complain, jiffies)) {
                        dprintk("NFS:       faulty NFS server %s:"
                                " (committed = %d) != (stable = %d)\n",
-                               server->nfs_client->cl_hostname,
+                               NFS_SERVER(data->inode)->nfs_client->cl_hostname,
                                resp->verf->committed, argp->stable);
                        complain = jiffies + 300 * HZ;
                }
index dc5a1bf..52cd976 100644 (file)
@@ -256,6 +256,8 @@ static void nfsd_last_thread(struct svc_serv *serv)
        nfsd_serv = NULL;
        nfsd_shutdown();
 
+       svc_rpcb_cleanup(serv);
+
        printk(KERN_WARNING "nfsd: last server has exited, flushing export "
                            "cache\n");
        nfsd_export_flush();
index 60a137b..ab2c634 100644 (file)
@@ -229,6 +229,7 @@ struct nfs_inode {
 #define NFS_INO_COMMIT         (7)             /* inode is committing unstable writes */
 #define NFS_INO_PNFS_COMMIT    (8)             /* use pnfs code for commit */
 #define NFS_INO_LAYOUTCOMMIT   (9)             /* layoutcommit required */
+#define NFS_INO_LAYOUTCOMMITTING (10)          /* layoutcommit inflight */
 
 static inline struct nfs_inode *NFS_I(const struct inode *inode)
 {
index f01ba8a..0e89aa0 100644 (file)
@@ -321,6 +321,16 @@ static inline struct device_node *of_parse_phandle(struct device_node *np,
        return NULL;
 }
 
+static inline int of_alias_get_id(struct device_node *np, const char *stem)
+{
+       return -ENOSYS;
+}
+
+static inline int of_machine_is_compatible(const char *compat)
+{
+       return 0;
+}
+
 #define of_match_ptr(_ptr)     NULL
 #define of_match_node(_matches, _node) NULL
 #endif /* CONFIG_OF */
index 492486a..3d8f9c4 100644 (file)
@@ -136,6 +136,8 @@ void                rpc_shutdown_client(struct rpc_clnt *);
 void           rpc_release_client(struct rpc_clnt *);
 void           rpc_task_release_client(struct rpc_task *);
 
+int            rpcb_create_local(void);
+void           rpcb_put_local(void);
 int            rpcb_register(u32, u32, int, unsigned short);
 int            rpcb_v4_register(const u32 program, const u32 version,
                                 const struct sockaddr *address,
index d8d5d93..35b37b1 100644 (file)
@@ -413,6 +413,7 @@ struct svc_procedure {
 /*
  * Function prototypes.
  */
+void svc_rpcb_cleanup(struct svc_serv *serv);
 struct svc_serv *svc_create(struct svc_program *, unsigned int,
                            void (*shutdown)(struct svc_serv *));
 struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
index 225560c..4b752d5 100644 (file)
@@ -653,6 +653,10 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_ERROR    0x0040
 #define V4L2_BUF_FLAG_TIMECODE 0x0100  /* timecode field is valid */
 #define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
+#define V4L2_BUF_FLAG_PREPARED 0x0400  /* Buffer is prepared for queuing */
+/* Cache handling flags */
+#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE      0x0800
+#define V4L2_BUF_FLAG_NO_CACHE_CLEAN           0x1000
 
 /*
  *     O V E R L A Y   P R E V I E W
@@ -1165,6 +1169,7 @@ enum v4l2_power_line_frequency {
        V4L2_CID_POWER_LINE_FREQUENCY_DISABLED  = 0,
        V4L2_CID_POWER_LINE_FREQUENCY_50HZ      = 1,
        V4L2_CID_POWER_LINE_FREQUENCY_60HZ      = 2,
+       V4L2_CID_POWER_LINE_FREQUENCY_AUTO      = 3,
 };
 #define V4L2_CID_HUE_AUTO                      (V4L2_CID_BASE+25)
 #define V4L2_CID_WHITE_BALANCE_TEMPERATURE     (V4L2_CID_BASE+26)
@@ -2138,6 +2143,23 @@ struct v4l2_dbg_chip_ident {
        __u32 revision;    /* chip revision, chip specific */
 } __attribute__ ((packed));
 
+/**
+ * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
+ * @index:     on return, index of the first created buffer
+ * @count:     entry: number of requested buffers,
+ *             return: number of created buffers
+ * @memory:    buffer memory type
+ * @format:    frame format, for which buffers are requested
+ * @reserved:  future extensions
+ */
+struct v4l2_create_buffers {
+       __u32                   index;
+       __u32                   count;
+       enum v4l2_memory        memory;
+       struct v4l2_format      format;
+       __u32                   reserved[8];
+};
+
 /*
  *     I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
@@ -2228,6 +2250,11 @@ struct v4l2_dbg_chip_ident {
 #define        VIDIOC_SUBSCRIBE_EVENT   _IOW('V', 90, struct v4l2_event_subscription)
 #define        VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription)
 
+/* Experimental, the below two ioctls may change over the next couple of kernel
+   versions */
+#define VIDIOC_CREATE_BUFS     _IOWR('V', 92, struct v4l2_create_buffers)
+#define VIDIOC_PREPARE_BUF     _IOWR('V', 93, struct v4l2_buffer)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
index 548bf11..00dbb7c 100644 (file)
 #ifndef __OV772X_H__
 #define __OV772X_H__
 
-#include <media/soc_camera.h>
-
 /* for flags */
 #define OV772X_FLAG_VFLIP      (1 << 0) /* Vertical flip image */
 #define OV772X_FLAG_HFLIP      (1 << 1) /* Horizontal flip image */
-#define OV772X_FLAG_8BIT       (1 << 2) /* default 10 bit */
 
 /*
  * for Edge ctrl
@@ -32,22 +29,23 @@ struct ov772x_edge_ctrl {
        unsigned char lower;
 };
 
-#define OV772X_MANUAL_EDGE_CTRL        0x80 /* un-used bit of strength */
-#define EDGE_STRENGTH_MASK     0x1F
-#define EDGE_THRESHOLD_MASK    0x0F
-#define EDGE_UPPER_MASK                0xFF
-#define EDGE_LOWER_MASK                0xFF
+#define OV772X_MANUAL_EDGE_CTRL                0x80 /* un-used bit of strength */
+#define OV772X_EDGE_STRENGTH_MASK      0x1F
+#define OV772X_EDGE_THRESHOLD_MASK     0x0F
+#define OV772X_EDGE_UPPER_MASK         0xFF
+#define OV772X_EDGE_LOWER_MASK         0xFF
 
 #define OV772X_AUTO_EDGECTRL(u, l)     \
 {                                      \
-       .upper = (u & EDGE_UPPER_MASK), \
-       .lower = (l & EDGE_LOWER_MASK), \
+       .upper = (u & OV772X_EDGE_UPPER_MASK),  \
+       .lower = (l & OV772X_EDGE_LOWER_MASK),  \
 }
 
-#define OV772X_MANUAL_EDGECTRL(s, t)                                   \
-{                                                                      \
-       .strength  = (s & EDGE_STRENGTH_MASK) | OV772X_MANUAL_EDGE_CTRL,\
-       .threshold = (t & EDGE_THRESHOLD_MASK),                         \
+#define OV772X_MANUAL_EDGECTRL(s, t)                   \
+{                                                      \
+       .strength  = (s & OV772X_EDGE_STRENGTH_MASK) |  \
+                       OV772X_MANUAL_EDGE_CTRL,        \
+       .threshold = (t & OV772X_EDGE_THRESHOLD_MASK),  \
 }
 
 /*
diff --git a/include/media/s5k6aa.h b/include/media/s5k6aa.h
new file mode 100644 (file)
index 0000000..ba34f70
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * S5K6AAFX camera sensor driver header
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef S5K6AA_H
+#define S5K6AA_H
+
+#include <media/v4l2-mediabus.h>
+
+/**
+ * struct s5k6aa_gpio - data structure describing a GPIO
+ * @gpio:  GPIO number
+ * @level: indicates active state of the @gpio
+ */
+struct s5k6aa_gpio {
+       int gpio;
+       int level;
+};
+
+/**
+ * struct s5k6aa_platform_data - s5k6aa driver platform data
+ * @set_power:   an additional callback to the board code, called
+ *               after enabling the regulators and before switching
+ *               the sensor off
+ * @mclk_frequency: sensor's master clock frequency in Hz
+ * @gpio_reset:  GPIO driving RESET pin
+ * @gpio_stby:   GPIO driving STBY pin
+ * @nlanes:      maximum number of MIPI-CSI lanes used
+ * @horiz_flip:  default horizontal image flip value, non zero to enable
+ * @vert_flip:   default vertical image flip value, non zero to enable
+ */
+
+struct s5k6aa_platform_data {
+       int (*set_power)(int enable);
+       unsigned long mclk_frequency;
+       struct s5k6aa_gpio gpio_reset;
+       struct s5k6aa_gpio gpio_stby;
+       enum v4l2_mbus_type bus_type;
+       u8 nlanes;
+       u8 horiz_flip;
+       u8 vert_flip;
+};
+
+#endif /* S5K6AA_H */
index 7582952..b1377b9 100644 (file)
 #ifndef SOC_CAMERA_H
 #define SOC_CAMERA_H
 
+#include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/pm.h>
 #include <linux/videodev2.h>
 #include <media/videobuf-core.h>
 #include <media/videobuf2-core.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 
 struct file;
@@ -37,8 +39,8 @@ struct soc_camera_device {
        unsigned char iface;            /* Host number */
        unsigned char devnum;           /* Device number per host */
        struct soc_camera_sense *sense; /* See comment in struct definition */
-       struct soc_camera_ops *ops;
        struct video_device *vdev;
+       struct v4l2_ctrl_handler ctrl_handler;
        const struct soc_camera_format_xlate *current_fmt;
        struct soc_camera_format_xlate *user_formats;
        int num_user_formats;
@@ -93,14 +95,10 @@ struct soc_camera_host_ops {
        int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *);
        int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
        int (*set_bus_param)(struct soc_camera_device *, __u32);
-       int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *);
-       int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *);
        int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
        int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
        int (*enum_fsizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
        unsigned int (*poll)(struct file *, poll_table *);
-       const struct v4l2_queryctrl *controls;
-       int num_controls;
 };
 
 #define SOCAM_SENSOR_INVERT_PCLK       (1 << 0)
@@ -193,13 +191,6 @@ struct soc_camera_format_xlate {
        const struct soc_mbus_pixelfmt *host_fmt;
 };
 
-struct soc_camera_ops {
-       unsigned long (*query_bus_param)(struct soc_camera_device *);
-       int (*set_bus_param)(struct soc_camera_device *, unsigned long);
-       const struct v4l2_queryctrl *controls;
-       int num_controls;
-};
-
 #define SOCAM_SENSE_PCLK_CHANGED       (1 << 0)
 
 /**
@@ -226,65 +217,18 @@ struct soc_camera_sense {
        unsigned long pixel_clock;
 };
 
-static inline struct v4l2_queryctrl const *soc_camera_find_qctrl(
-       struct soc_camera_ops *ops, int id)
-{
-       int i;
-
-       for (i = 0; i < ops->num_controls; i++)
-               if (ops->controls[i].id == id)
-                       return &ops->controls[i];
-
-       return NULL;
-}
-
-#define SOCAM_MASTER                   (1 << 0)
-#define SOCAM_SLAVE                    (1 << 1)
-#define SOCAM_HSYNC_ACTIVE_HIGH                (1 << 2)
-#define SOCAM_HSYNC_ACTIVE_LOW         (1 << 3)
-#define SOCAM_VSYNC_ACTIVE_HIGH                (1 << 4)
-#define SOCAM_VSYNC_ACTIVE_LOW         (1 << 5)
-#define SOCAM_DATAWIDTH_4              (1 << 6)
-#define SOCAM_DATAWIDTH_8              (1 << 7)
-#define SOCAM_DATAWIDTH_9              (1 << 8)
-#define SOCAM_DATAWIDTH_10             (1 << 9)
-#define SOCAM_DATAWIDTH_15             (1 << 10)
-#define SOCAM_DATAWIDTH_16             (1 << 11)
-#define SOCAM_PCLK_SAMPLE_RISING       (1 << 12)
-#define SOCAM_PCLK_SAMPLE_FALLING      (1 << 13)
-#define SOCAM_DATA_ACTIVE_HIGH         (1 << 14)
-#define SOCAM_DATA_ACTIVE_LOW          (1 << 15)
-#define SOCAM_MIPI_1LANE               (1 << 16)
-#define SOCAM_MIPI_2LANE               (1 << 17)
-#define SOCAM_MIPI_3LANE               (1 << 18)
-#define SOCAM_MIPI_4LANE               (1 << 19)
-#define SOCAM_MIPI     (SOCAM_MIPI_1LANE | SOCAM_MIPI_2LANE | \
-                       SOCAM_MIPI_3LANE | SOCAM_MIPI_4LANE)
+#define SOCAM_DATAWIDTH(x)     BIT((x) - 1)
+#define SOCAM_DATAWIDTH_4      SOCAM_DATAWIDTH(4)
+#define SOCAM_DATAWIDTH_8      SOCAM_DATAWIDTH(8)
+#define SOCAM_DATAWIDTH_9      SOCAM_DATAWIDTH(9)
+#define SOCAM_DATAWIDTH_10     SOCAM_DATAWIDTH(10)
+#define SOCAM_DATAWIDTH_15     SOCAM_DATAWIDTH(15)
+#define SOCAM_DATAWIDTH_16     SOCAM_DATAWIDTH(16)
 
 #define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \
                              SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \
                              SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_16)
 
-static inline unsigned long soc_camera_bus_param_compatible(
-                       unsigned long camera_flags, unsigned long bus_flags)
-{
-       unsigned long common_flags, hsync, vsync, pclk, data, buswidth, mode;
-       unsigned long mipi;
-
-       common_flags = camera_flags & bus_flags;
-
-       hsync = common_flags & (SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW);
-       vsync = common_flags & (SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW);
-       pclk = common_flags & (SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING);
-       data = common_flags & (SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW);
-       mode = common_flags & (SOCAM_MASTER | SOCAM_SLAVE);
-       buswidth = common_flags & SOCAM_DATAWIDTH_MASK;
-       mipi = common_flags & SOCAM_MIPI;
-
-       return ((!hsync || !vsync || !pclk || !data || !mode || !buswidth) && !mipi) ? 0 :
-               common_flags;
-}
-
 static inline void soc_camera_limit_side(int *start, int *length,
                unsigned int start_min,
                unsigned int length_min, unsigned int length_max)
@@ -300,23 +244,37 @@ static inline void soc_camera_limit_side(int *start, int *length,
                *start = start_min + length_max - *length;
 }
 
-extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
-                                                  unsigned long flags);
+unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
+                                           unsigned long flags);
+unsigned long soc_camera_apply_board_flags(struct soc_camera_link *icl,
+                                          const struct v4l2_mbus_config *cfg);
 
 /* This is only temporary here - until v4l2-subdev begins to link to video_device */
 #include <linux/i2c.h>
-static inline struct video_device *soc_camera_i2c_to_vdev(struct i2c_client *client)
+static inline struct video_device *soc_camera_i2c_to_vdev(const struct i2c_client *client)
+{
+       struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id;
+       return icd ? icd->vdev : NULL;
+}
+
+static inline struct soc_camera_link *soc_camera_i2c_to_link(const struct i2c_client *client)
+{
+       return client->dev.platform_data;
+}
+
+static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(const struct video_device *vdev)
 {
-       struct soc_camera_device *icd = client->dev.platform_data;
-       return icd->vdev;
+       struct soc_camera_device *icd = dev_get_drvdata(vdev->parent);
+       return soc_camera_to_subdev(icd);
 }
 
-static inline struct soc_camera_device *soc_camera_from_vb2q(struct vb2_queue *vq)
+static inline struct soc_camera_device *soc_camera_from_vb2q(const struct vb2_queue *vq)
 {
        return container_of(vq, struct soc_camera_device, vb2_vidq);
 }
 
-static inline struct soc_camera_device *soc_camera_from_vbq(struct videobuf_queue *vq)
+static inline struct soc_camera_device *soc_camera_from_vbq(const struct videobuf_queue *vq)
 {
        return container_of(vq, struct soc_camera_device, vb_vidq);
 }
index 74f0fa1..8aa4200 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/videodev2.h>
 #include <media/soc_camera.h>
+#include <media/v4l2-mediabus.h>
 
 struct device;
 
@@ -20,7 +21,8 @@ struct soc_camera_platform_info {
        const char *format_name;
        unsigned long format_depth;
        struct v4l2_mbus_framefmt format;
-       unsigned long bus_param;
+       unsigned long mbus_param;
+       enum v4l2_mbus_type mbus_type;
        struct soc_camera_device *icd;
        int (*set_capture)(struct soc_camera_platform_info *info, int enable);
 };
index fae4325..73f1e7e 100644 (file)
@@ -82,5 +82,7 @@ const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
 s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf);
 int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
                        unsigned int *numerator, unsigned int *denominator);
+unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
+                                       unsigned int flags);
 
 #endif
index dd9f1e7..4d1c74a 100644 (file)
@@ -122,6 +122,8 @@ struct v4l2_ioctl_ops {
        int (*vidioc_qbuf)    (struct file *file, void *fh, struct v4l2_buffer *b);
        int (*vidioc_dqbuf)   (struct file *file, void *fh, struct v4l2_buffer *b);
 
+       int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b);
+       int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b);
 
        int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i);
        int (*vidioc_g_fbuf)   (struct file *file, void *fh,
index 257da1a..f0f3358 100644 (file)
@@ -158,6 +158,7 @@ struct v4l2_subdev_core_ops {
        int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
        int (*try_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
        int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm);
+       int (*g_std)(struct v4l2_subdev *sd, v4l2_std_id *norm);
        int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm);
        long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -534,13 +535,13 @@ struct v4l2_subdev {
        void *dev_priv;
        void *host_priv;
        /* subdev device node */
-       struct video_device devnode;
+       struct video_device *devnode;
 };
 
 #define media_entity_to_v4l2_subdev(ent) \
        container_of(ent, struct v4l2_subdev, entity)
 #define vdev_to_v4l2_subdev(vdev) \
-       container_of(vdev, struct v4l2_subdev, devnode)
+       video_get_drvdata(vdev)
 
 /*
  * Used for storing subdev information per file handle
index ea55c08..a15d1f1 100644 (file)
@@ -105,6 +105,7 @@ enum vb2_fileio_flags {
 /**
  * enum vb2_buffer_state - current video buffer state
  * @VB2_BUF_STATE_DEQUEUED:    buffer under userspace control
+ * @VB2_BUF_STATE_PREPARED:    buffer prepared in videobuf and by the driver
  * @VB2_BUF_STATE_QUEUED:      buffer queued in videobuf, but not in driver
  * @VB2_BUF_STATE_ACTIVE:      buffer queued in driver and possibly used
  *                             in a hardware operation
@@ -116,6 +117,7 @@ enum vb2_fileio_flags {
  */
 enum vb2_buffer_state {
        VB2_BUF_STATE_DEQUEUED,
+       VB2_BUF_STATE_PREPARED,
        VB2_BUF_STATE_QUEUED,
        VB2_BUF_STATE_ACTIVE,
        VB2_BUF_STATE_DONE,
@@ -167,13 +169,21 @@ struct vb2_buffer {
 /**
  * struct vb2_ops - driver-specific callbacks
  *
- * @queue_setup:       called from a VIDIOC_REQBUFS handler, before
- *                     memory allocation; driver should return the required
- *                     number of buffers in num_buffers, the required number
- *                     of planes per buffer in num_planes; the size of each
- *                     plane should be set in the sizes[] array and optional
- *                     per-plane allocator specific context in alloc_ctxs[]
- *                     array
+ * @queue_setup:       called from VIDIOC_REQBUFS and VIDIOC_CREATE_BUFS
+ *                     handlers before memory allocation, or, if
+ *                     *num_planes != 0, after the allocation to verify a
+ *                     smaller number of buffers. Driver should return
+ *                     the required number of buffers in *num_buffers, the
+ *                     required number of planes per buffer in *num_planes; the
+ *                     size of each plane should be set in the sizes[] array
+ *                     and optional per-plane allocator specific context in the
+ *                     alloc_ctxs[] array. When called from VIDIOC_REQBUFS,
+ *                     fmt == NULL, the driver has to use the currently
+ *                     configured format and *num_buffers is the total number
+ *                     of buffers, that are being allocated. When called from
+ *                     VIDIOC_CREATE_BUFS, fmt != NULL and it describes the
+ *                     target frame format. In this case *num_buffers are being
+ *                     allocated additionally to q->num_buffers.
  * @wait_prepare:      release any locks taken while calling vb2 functions;
  *                     it is called before an ioctl needs to wait for a new
  *                     buffer to arrive; required to avoid a deadlock in
@@ -186,11 +196,11 @@ struct vb2_buffer {
  *                     perform additional buffer-related initialization;
  *                     initialization failure (return != 0) will prevent
  *                     queue setup from completing successfully; optional
- * @buf_prepare:       called every time the buffer is queued from userspace;
- *                     drivers may perform any initialization required before
- *                     each hardware operation in this callback;
- *                     if an error is returned, the buffer will not be queued
- *                     in driver; optional
+ * @buf_prepare:       called every time the buffer is queued from userspace
+ *                     and from the VIDIOC_PREPARE_BUF ioctl; drivers may
+ *                     perform any initialization required before each hardware
+ *                     operation in this callback; if an error is returned, the
+ *                     buffer will not be queued in driver; optional
  * @buf_finish:                called before every dequeue of the buffer back to
  *                     userspace; drivers may perform any operations required
  *                     before userspace accesses the buffer; optional
@@ -216,9 +226,9 @@ struct vb2_buffer {
  *                     pre-queued buffers before calling STREAMON
  */
 struct vb2_ops {
-       int (*queue_setup)(struct vb2_queue *q, unsigned int *num_buffers,
-                          unsigned int *num_planes, unsigned int sizes[],
-                          void *alloc_ctxs[]);
+       int (*queue_setup)(struct vb2_queue *q, const struct v4l2_format *fmt,
+                          unsigned int *num_buffers, unsigned int *num_planes,
+                          unsigned int sizes[], void *alloc_ctxs[]);
 
        void (*wait_prepare)(struct vb2_queue *q);
        void (*wait_finish)(struct vb2_queue *q);
@@ -298,6 +308,9 @@ int vb2_wait_for_all_buffers(struct vb2_queue *q);
 int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b);
 int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
 
+int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create);
+int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b);
+
 int vb2_queue_init(struct vb2_queue *q);
 
 void vb2_queue_release(struct vb2_queue *q);
@@ -309,6 +322,13 @@ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
 int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type);
 
 int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma);
+#ifndef CONFIG_MMU
+unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
+                                   unsigned long addr,
+                                   unsigned long len,
+                                   unsigned long pgoff,
+                                   unsigned long flags);
+#endif
 unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait);
 size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
                loff_t *ppos, int nonblock);
index 4cb70dc..e50502d 100644 (file)
@@ -129,6 +129,9 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
        for (i = 0; i < groups ; i++)
                if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i))
                        return 0;
+       if (groups < NFS_NGROUPS &&
+           cred->uc_gids[groups] != NOGROUP)
+               return 0;
        return 1;
 }
 
index f588b85..8761bf8 100644 (file)
@@ -114,6 +114,9 @@ static struct rpc_program   rpcb_program;
 static struct rpc_clnt *       rpcb_local_clnt;
 static struct rpc_clnt *       rpcb_local_clnt4;
 
+DEFINE_SPINLOCK(rpcb_clnt_lock);
+unsigned int                   rpcb_users;
+
 struct rpcbind_args {
        struct rpc_xprt *       r_xprt;
 
@@ -161,6 +164,56 @@ static void rpcb_map_release(void *data)
        kfree(map);
 }
 
+static int rpcb_get_local(void)
+{
+       int cnt;
+
+       spin_lock(&rpcb_clnt_lock);
+       if (rpcb_users)
+               rpcb_users++;
+       cnt = rpcb_users;
+       spin_unlock(&rpcb_clnt_lock);
+
+       return cnt;
+}
+
+void rpcb_put_local(void)
+{
+       struct rpc_clnt *clnt = rpcb_local_clnt;
+       struct rpc_clnt *clnt4 = rpcb_local_clnt4;
+       int shutdown;
+
+       spin_lock(&rpcb_clnt_lock);
+       if (--rpcb_users == 0) {
+               rpcb_local_clnt = NULL;
+               rpcb_local_clnt4 = NULL;
+       }
+       shutdown = !rpcb_users;
+       spin_unlock(&rpcb_clnt_lock);
+
+       if (shutdown) {
+               /*
+                * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
+                */
+               if (clnt4)
+                       rpc_shutdown_client(clnt4);
+               if (clnt)
+                       rpc_shutdown_client(clnt);
+       }
+}
+
+static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
+{
+       /* Protected by rpcb_create_local_mutex */
+       rpcb_local_clnt = clnt;
+       rpcb_local_clnt4 = clnt4;
+       smp_wmb(); 
+       rpcb_users = 1;
+       dprintk("RPC:       created new rpcb local clients (rpcb_local_clnt: "
+                       "%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt,
+                       rpcb_local_clnt4);
+}
+
 /*
  * Returns zero on success, otherwise a negative errno value
  * is returned.
@@ -205,9 +258,7 @@ static int rpcb_create_local_unix(void)
                clnt4 = NULL;
        }
 
-       /* Protected by rpcb_create_local_mutex */
-       rpcb_local_clnt = clnt;
-       rpcb_local_clnt4 = clnt4;
+       rpcb_set_local(clnt, clnt4);
 
 out:
        return result;
@@ -259,9 +310,7 @@ static int rpcb_create_local_net(void)
                clnt4 = NULL;
        }
 
-       /* Protected by rpcb_create_local_mutex */
-       rpcb_local_clnt = clnt;
-       rpcb_local_clnt4 = clnt4;
+       rpcb_set_local(clnt, clnt4);
 
 out:
        return result;
@@ -271,16 +320,16 @@ out:
  * Returns zero on success, otherwise a negative errno value
  * is returned.
  */
-static int rpcb_create_local(void)
+int rpcb_create_local(void)
 {
        static DEFINE_MUTEX(rpcb_create_local_mutex);
        int result = 0;
 
-       if (rpcb_local_clnt)
+       if (rpcb_get_local())
                return result;
 
        mutex_lock(&rpcb_create_local_mutex);
-       if (rpcb_local_clnt)
+       if (rpcb_get_local())
                goto out;
 
        if (rpcb_create_local_unix() != 0)
@@ -382,11 +431,6 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
        struct rpc_message msg = {
                .rpc_argp       = &map,
        };
-       int error;
-
-       error = rpcb_create_local();
-       if (error)
-               return error;
 
        dprintk("RPC:       %sregistering (%u, %u, %d, %u) with local "
                        "rpcbind\n", (port ? "" : "un"),
@@ -522,11 +566,7 @@ int rpcb_v4_register(const u32 program, const u32 version,
        struct rpc_message msg = {
                .rpc_argp       = &map,
        };
-       int error;
 
-       error = rpcb_create_local();
-       if (error)
-               return error;
        if (rpcb_local_clnt4 == NULL)
                return -EPROTONOSUPPORT;
 
@@ -1060,15 +1100,3 @@ static struct rpc_program rpcb_program = {
        .version        = rpcb_version,
        .stats          = &rpcb_stats,
 };
-
-/**
- * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
- *
- */
-void cleanup_rpcb_clnt(void)
-{
-       if (rpcb_local_clnt4)
-               rpc_shutdown_client(rpcb_local_clnt4);
-       if (rpcb_local_clnt)
-               rpc_shutdown_client(rpcb_local_clnt);
-}
index 9d08091..8ec9778 100644 (file)
@@ -61,8 +61,6 @@ static struct pernet_operations sunrpc_net_ops = {
 
 extern struct cache_detail unix_gid_cache;
 
-extern void cleanup_rpcb_clnt(void);
-
 static int __init
 init_sunrpc(void)
 {
@@ -102,7 +100,6 @@ out:
 static void __exit
 cleanup_sunrpc(void)
 {
-       cleanup_rpcb_clnt();
        rpcauth_remove_module();
        cleanup_socket_xprt();
        svc_cleanup_xprt_sock();
index dd5cc00..6e03888 100644 (file)
@@ -366,6 +366,42 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
        return &serv->sv_pools[pidx % serv->sv_nrpools];
 }
 
+static int svc_rpcb_setup(struct svc_serv *serv)
+{
+       int err;
+
+       err = rpcb_create_local();
+       if (err)
+               return err;
+
+       /* Remove any stale portmap registrations */
+       svc_unregister(serv);
+       return 0;
+}
+
+void svc_rpcb_cleanup(struct svc_serv *serv)
+{
+       svc_unregister(serv);
+       rpcb_put_local();
+}
+EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
+
+static int svc_uses_rpcbind(struct svc_serv *serv)
+{
+       struct svc_program      *progp;
+       unsigned int            i;
+
+       for (progp = serv->sv_program; progp; progp = progp->pg_next) {
+               for (i = 0; i < progp->pg_nvers; i++) {
+                       if (progp->pg_vers[i] == NULL)
+                               continue;
+                       if (progp->pg_vers[i]->vs_hidden == 0)
+                               return 1;
+               }
+       }
+
+       return 0;
+}
 
 /*
  * Create an RPC service
@@ -431,8 +467,15 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
                spin_lock_init(&pool->sp_lock);
        }
 
-       /* Remove any stale portmap registrations */
-       svc_unregister(serv);
+       if (svc_uses_rpcbind(serv)) {
+               if (svc_rpcb_setup(serv) < 0) {
+                       kfree(serv->sv_pools);
+                       kfree(serv);
+                       return NULL;
+               }
+               if (!serv->sv_shutdown)
+                       serv->sv_shutdown = svc_rpcb_cleanup;
+       }
 
        return serv;
 }
@@ -500,7 +543,6 @@ svc_destroy(struct svc_serv *serv)
        if (svc_serv_is_pooled(serv))
                svc_pool_map_put();
 
-       svc_unregister(serv);
        kfree(serv->sv_pools);
        kfree(serv);
 }
index a70ee7f..031e215 100644 (file)
@@ -272,7 +272,14 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
                        if (get_user(device, (int __user *)arg))
                                return -EFAULT;
                        mutex_lock(&register_mutex);
-                       device = device < 0 ? 0 : device + 1;
+
+                       if (device < 0)
+                               device = 0;
+                       else if (device < SNDRV_MINOR_HWDEPS)
+                               device++;
+                       else
+                               device = SNDRV_MINOR_HWDEPS;
+
                        while (device < SNDRV_MINOR_HWDEPS) {
                                if (snd_hwdep_search(card, device))
                                        break;
index 72e5885..7e7d078 100644 (file)
@@ -756,8 +756,6 @@ static int get_line_from_fw(char *buf, int size, struct firmware *fw)
        }
        if (!fw->size)
                return 0;
-       if (size < fw->size)
-               size = fw->size;
 
        for (len = 0; len < fw->size; len++) {
                if (!*p)
index 81e12c0..79f49e2 100644 (file)
@@ -442,6 +442,8 @@ struct auto_pin_cfg {
        (cfg & AC_DEFCFG_SEQUENCE)
 #define get_defcfg_device(cfg) \
        ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
+#define get_defcfg_misc(cfg) \
+       ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT)
 
 /* bit-flags for snd_hda_parse_pin_def_config() behavior */
 #define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */
@@ -509,6 +511,8 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
 static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
 {
        return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) &&
+               !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) &
+                 AC_DEFCFG_MISC_NO_PRESENCE)) &&
                (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP);
 }
 
index 3425401..aac3bfa 100644 (file)
@@ -1006,7 +1006,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
        unsigned int caps, config;
        int pin_idx;
        struct hdmi_spec_per_pin *per_pin;
-       struct hdmi_eld *eld;
        int err;
 
        caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP);
@@ -1023,7 +1022,6 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
 
        pin_idx = spec->num_pins;
        per_pin = &spec->pins[pin_idx];
-       eld = &per_pin->sink_eld;
 
        per_pin->pin_nid = pin_nid;
 
@@ -1576,7 +1574,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
                                     struct snd_pcm_substream *substream)
 {
        int chs;
-       unsigned int dataDCC1, dataDCC2, channel_id;
+       unsigned int dataDCC2, channel_id;
        int i;
        struct hdmi_spec *spec = codec->spec;
        struct hda_spdif_out *spdif =
@@ -1586,7 +1584,6 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
 
        chs = substream->runtime->channels;
 
-       dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT;
        dataDCC2 = 0x2;
 
        /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
index 8f93b97..80d6add 100644 (file)
@@ -1604,27 +1604,29 @@ static void alc_auto_init_digital(struct hda_codec *codec)
 static void alc_auto_parse_digital(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       int i, err;
+       int i, err, nums;
        hda_nid_t dig_nid;
 
        /* support multiple SPDIFs; the secondary is set up as a slave */
+       nums = 0;
        for (i = 0; i < spec->autocfg.dig_outs; i++) {
                hda_nid_t conn[4];
                err = snd_hda_get_connections(codec,
                                              spec->autocfg.dig_out_pins[i],
                                              conn, ARRAY_SIZE(conn));
-               if (err < 0)
+               if (err <= 0)
                        continue;
                dig_nid = conn[0]; /* assume the first element is audio-out */
-               if (!i) {
+               if (!nums) {
                        spec->multiout.dig_out_nid = dig_nid;
                        spec->dig_out_type = spec->autocfg.dig_out_type[0];
                } else {
                        spec->multiout.slave_dig_outs = spec->slave_dig_outs;
-                       if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
+                       if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
                                break;
-                       spec->slave_dig_outs[i - 1] = dig_nid;
+                       spec->slave_dig_outs[nums - 1] = dig_nid;
                }
+               nums++;
        }
 
        if (spec->autocfg.dig_in_pin) {
@@ -2270,6 +2272,7 @@ static int alc_build_pcms(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        struct hda_pcm *info = spec->pcm_rec;
        const struct hda_pcm_stream *p;
+       bool have_multi_adcs;
        int i;
 
        codec->num_pcms = 1;
@@ -2348,8 +2351,11 @@ static int alc_build_pcms(struct hda_codec *codec)
        /* If the use of more than one ADC is requested for the current
         * model, configure a second analog capture-only PCM.
         */
+       have_multi_adcs = (spec->num_adc_nids > 1) &&
+               !spec->dyn_adc_switch && !spec->auto_mic &&
+               (!spec->input_mux || spec->input_mux->num_items > 1);
        /* Additional Analaog capture for index #2 */
-       if (spec->alt_dac_nid || spec->num_adc_nids > 1) {
+       if (spec->alt_dac_nid || have_multi_adcs) {
                codec->num_pcms = 3;
                info = spec->pcm_rec + 2;
                info->name = spec->stream_name_analog;
@@ -2365,7 +2371,7 @@ static int alc_build_pcms(struct hda_codec *codec)
                                alc_pcm_null_stream;
                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
                }
-               if (spec->num_adc_nids > 1) {
+               if (have_multi_adcs) {
                        p = spec->stream_analog_alt_capture;
                        if (!p)
                                p = &alc_pcm_analog_alt_capture;
@@ -2657,7 +2663,6 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec)
        hda_nid_t *adc_nids = spec->private_adc_nids;
        hda_nid_t *cap_nids = spec->private_capsrc_nids;
        int max_nums = ARRAY_SIZE(spec->private_adc_nids);
-       bool indep_capsrc = false;
        int i, nums = 0;
 
        nid = codec->start_nid;
@@ -2679,13 +2684,11 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec)
                                break;
                        if (type == AC_WID_AUD_SEL) {
                                cap_nids[nums] = src;
-                               indep_capsrc = true;
                                break;
                        }
                        n = snd_hda_get_conn_list(codec, src, &list);
                        if (n > 1) {
                                cap_nids[nums] = src;
-                               indep_capsrc = true;
                                break;
                        } else if (n != 1)
                                break;
index 59a52a4..de4c360 100644 (file)
@@ -3791,9 +3791,10 @@ static int is_dual_headphones(struct hda_codec *codec)
 }
 
 
-static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in)
+static int stac92xx_parse_auto_config(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec = codec->spec;
+       hda_nid_t dig_out = 0, dig_in = 0;
        int hp_swap = 0;
        int i, err;
 
@@ -3976,6 +3977,22 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
        if (spec->multiout.max_channels > 2)
                spec->surr_switch = 1;
 
+       /* find digital out and in converters */
+       for (i = codec->start_nid; i < codec->start_nid + codec->num_nodes; i++) {
+               unsigned int wid_caps = get_wcaps(codec, i);
+               if (wid_caps & AC_WCAP_DIGITAL) {
+                       switch (get_wcaps_type(wid_caps)) {
+                       case AC_WID_AUD_OUT:
+                               if (!dig_out)
+                                       dig_out = i;
+                               break;
+                       case AC_WID_AUD_IN:
+                               if (!dig_in)
+                                       dig_in = i;
+                               break;
+                       }
+               }
+       }
        if (spec->autocfg.dig_outs)
                spec->multiout.dig_out_nid = dig_out;
        if (dig_in && spec->autocfg.dig_in_pin)
@@ -5279,7 +5296,7 @@ static int patch_stac925x(struct hda_codec *codec)
        spec->capvols = stac925x_capvols;
        spec->capsws = stac925x_capsws;
 
-       err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
+       err = stac92xx_parse_auto_config(codec);
        if (!err) {
                if (spec->board_config < 0) {
                        printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -5420,7 +5437,7 @@ again:
        spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
        spec->pwr_nids = stac92hd73xx_pwr_nids;
 
-       err = stac92xx_parse_auto_config(codec, 0x25, 0x27);
+       err = stac92xx_parse_auto_config(codec);
 
        if (!err) {
                if (spec->board_config < 0) {
@@ -5629,26 +5646,8 @@ again:
                stac92xx_set_config_regs(codec,
                                stac92hd83xxx_brd_tbl[spec->board_config]);
 
-       switch (codec->vendor_id) {
-       case 0x111d76d1:
-       case 0x111d76d9:
-       case 0x111d76df:
-       case 0x111d76e5:
-       case 0x111d7666:
-       case 0x111d7667:
-       case 0x111d7668:
-       case 0x111d7669:
-       case 0x111d76e3:
-       case 0x111d7604:
-       case 0x111d76d4:
-       case 0x111d7605:
-       case 0x111d76d5:
-       case 0x111d76e7:
-               if (spec->board_config == STAC_92HD83XXX_PWR_REF)
-                       break;
+       if (spec->board_config != STAC_92HD83XXX_PWR_REF)
                spec->num_pwrs = 0;
-               break;
-       }
 
        codec->patch_ops = stac92xx_patch_ops;
 
@@ -5675,7 +5674,7 @@ again:
        }
 #endif 
 
-       err = stac92xx_parse_auto_config(codec, 0x1d, 0);
+       err = stac92xx_parse_auto_config(codec);
        if (!err) {
                if (spec->board_config < 0) {
                        printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -5996,7 +5995,7 @@ again:
 
        spec->multiout.dac_nids = spec->dac_nids;
 
-       err = stac92xx_parse_auto_config(codec, 0x21, 0);
+       err = stac92xx_parse_auto_config(codec);
        if (!err) {
                if (spec->board_config < 0) {
                        printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -6105,7 +6104,7 @@ static int patch_stac922x(struct hda_codec *codec)
 
        spec->multiout.dac_nids = spec->dac_nids;
        
-       err = stac92xx_parse_auto_config(codec, 0x08, 0x09);
+       err = stac92xx_parse_auto_config(codec);
        if (!err) {
                if (spec->board_config < 0) {
                        printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -6230,7 +6229,7 @@ static int patch_stac927x(struct hda_codec *codec)
        spec->aloopback_shift = 0;
        spec->eapd_switch = 1;
 
-       err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
+       err = stac92xx_parse_auto_config(codec);
        if (!err) {
                if (spec->board_config < 0) {
                        printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -6355,7 +6354,7 @@ static int patch_stac9205(struct hda_codec *codec)
                break;
        }
 
-       err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
+       err = stac92xx_parse_auto_config(codec);
        if (!err) {
                if (spec->board_config < 0) {
                        printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -6460,7 +6459,7 @@ static int patch_stac9872(struct hda_codec *codec)
        spec->capvols = stac9872_capvols;
        spec->capsws = stac9872_capsws;
 
-       err = stac92xx_parse_auto_config(codec, 0x10, 0x12);
+       err = stac92xx_parse_auto_config(codec);
        if (err < 0) {
                stac92xx_free(codec);
                return -EINVAL;
@@ -6565,6 +6564,18 @@ static const struct hda_codec_preset snd_hda_preset_sigmatel[] = {
        { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx},
        { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx},
        { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx},
+       { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx},
        {} /* terminator */
 };
 
index 417d62a..0b020a9 100644 (file)
@@ -3700,13 +3700,8 @@ static const struct hda_verb vt1812_init_verbs[] = {
 static void set_widgets_power_state_vt1812(struct hda_codec *codec)
 {
        struct via_spec *spec = codec->spec;
-       int imux_is_smixer =
-       snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
        unsigned int parm;
        unsigned int present;
-       /* MUX10 (1eh) = stereo mixer */
-       imux_is_smixer =
-       snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
        /* inputs */
        /* PW 5/6/7 (29h/2ah/2bh) */
        parm = AC_PWRST_D3;
index 6a5b387..45b2055 100644 (file)
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
 
+#ifdef CONFIG_KVM_GUEST
+#include <linux/kvm_para.h>
+#else
+#define kvm_para_available() (0)
+#endif
+
 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455");
 MODULE_LICENSE("GPL");
@@ -77,6 +83,7 @@ static int buggy_semaphore;
 static int buggy_irq = -1; /* auto-check */
 static int xbox;
 static int spdif_aclink = -1;
+static int inside_vm = -1;
 
 module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
@@ -94,6 +101,8 @@ module_param(xbox, bool, 0444);
 MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
 module_param(spdif_aclink, int, 0444);
 MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
+module_param(inside_vm, bool, 0444);
+MODULE_PARM_DESC(inside_vm, "KVM/Parallels optimization.");
 
 /* just for backward compatibility */
 static int enable;
@@ -400,6 +409,7 @@ struct intel8x0 {
        unsigned buggy_irq: 1;          /* workaround for buggy mobos */
        unsigned xbox: 1;               /* workaround for Xbox AC'97 detection */
        unsigned buggy_semaphore: 1;    /* workaround for buggy codec semaphore */
+       unsigned inside_vm: 1;          /* enable VM optimization */
 
        int spdif_idx;  /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
        unsigned int sdm_saved; /* SDM reg value */
@@ -1065,8 +1075,11 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs
                        udelay(10);
                        continue;
                }
-               if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) &&
-                   ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
+               if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV))
+                       continue;
+               if (chip->inside_vm)
+                       break;
+               if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
                        break;
        } while (timeout--);
        ptr = ichdev->last_pos;
@@ -2984,6 +2997,10 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
        if (xbox)
                chip->xbox = 1;
 
+       chip->inside_vm = inside_vm;
+       if (inside_vm)
+               printk(KERN_INFO "intel8x0: enable KVM optimization\n");
+
        if (pci->vendor == PCI_VENDOR_ID_INTEL &&
            pci->device == PCI_DEVICE_ID_INTEL_440MX)
                chip->fix_nocache = 1; /* enable workaround */
@@ -3226,6 +3243,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
                        buggy_irq = 0;
        }
 
+       if (inside_vm < 0) {
+               /* detect KVM and Parallels virtual environments */
+               inside_vm = kvm_para_available();
+#if defined(__i386__) || defined(__x86_64__)
+               inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR);
+#endif
+       }
+
        if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
                                       &chip)) < 0) {
                snd_card_free(card);
index 1c6d1e1..f742202 100644 (file)
@@ -151,7 +151,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
 #define HDSP_PROGRAM           0x020
 #define HDSP_CONFIG_MODE_0     0x040
 #define HDSP_CONFIG_MODE_1     0x080
-#define HDSP_VERSION_BIT       0x100
+#define HDSP_VERSION_BIT       (0x100 | HDSP_S_LOAD)
 #define HDSP_BIGENDIAN_MODE     0x200
 #define HDSP_RD_MULTIPLE        0x400
 #define HDSP_9652_ENABLE_MIXER  0x800
index 6e2f7ef..15a6c3b 100644 (file)
@@ -520,16 +520,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
 #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
 #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
 
-/* revisions >= 230 indicate AES32 card */
-#define HDSPM_MADI_ANCIENT_REV 204
-#define HDSPM_MADI_OLD_REV     207
-#define HDSPM_MADI_REV         210
 #define HDSPM_RAYDAT_REV       211
 #define HDSPM_AIO_REV          212
 #define HDSPM_MADIFACE_REV     213
-#define HDSPM_AES_REV          240
-#define HDSPM_AES32_REV                234
-#define HDSPM_AES32_OLD_REV    233
 
 /* speed factor modes */
 #define HDSPM_SPEED_SINGLE 0
@@ -6253,7 +6246,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
                        status.card_specific.madi.madi_input =
                                (statusregister & HDSPM_AB_int) ? 1 : 0;
                        status.card_specific.madi.channel_format =
-                               (statusregister & HDSPM_TX_64ch) ? 1 : 0;
+                               (statusregister & HDSPM_RX_64ch) ? 1 : 0;
                        /* TODO: Mac driver sets it when f_s>48kHz */
                        status.card_specific.madi.frame_format = 0;
 
@@ -6503,13 +6496,6 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
        strcpy(card->driver, "HDSPM");
 
        switch (hdspm->firmware_rev) {
-       case HDSPM_MADI_REV:
-       case HDSPM_MADI_OLD_REV:
-       case HDSPM_MADI_ANCIENT_REV:
-               hdspm->io_type = MADI;
-               hdspm->card_name = "RME MADI";
-               hdspm->midiPorts = 3;
-               break;
        case HDSPM_RAYDAT_REV:
                hdspm->io_type = RayDAT;
                hdspm->card_name = "RME RayDAT";
@@ -6525,17 +6511,25 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
                hdspm->card_name = "RME MADIface";
                hdspm->midiPorts = 1;
                break;
-       case HDSPM_AES_REV:
-       case HDSPM_AES32_REV:
-       case HDSPM_AES32_OLD_REV:
-               hdspm->io_type = AES32;
-               hdspm->card_name = "RME AES32";
-               hdspm->midiPorts = 2;
-               break;
        default:
-               snd_printk(KERN_ERR "HDSPM: unknown firmware revision %x\n",
+               if ((hdspm->firmware_rev == 0xf0) ||
+                       ((hdspm->firmware_rev >= 0xe6) &&
+                                       (hdspm->firmware_rev <= 0xea))) {
+                       hdspm->io_type = AES32;
+                       hdspm->card_name = "RME AES32";
+                       hdspm->midiPorts = 2;
+               } else if ((hdspm->firmware_rev == 0xd5) ||
+                       ((hdspm->firmware_rev >= 0xc8)  &&
+                               (hdspm->firmware_rev <= 0xcf))) {
+                       hdspm->io_type = MADI;
+                       hdspm->card_name = "RME MADI";
+                       hdspm->midiPorts = 3;
+               } else {
+                       snd_printk(KERN_ERR
+                               "HDSPM: unknown firmware revision %x\n",
                                hdspm->firmware_rev);
-               return -ENODEV;
+                       return -ENODEV;
+               }
        }
 
        err = pci_enable_device(pci);
index ab27dbc..336de8f 100644 (file)
@@ -430,6 +430,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
                iface_reg |= TLV320AIC23_MS_MASTER;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
+               iface_reg &= ~TLV320AIC23_MS_MASTER;
                break;
        default:
                return -EINVAL;
index 7a49390..87d5ef1 100644 (file)
@@ -1023,6 +1023,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
                aic3x->master = 0;
+               iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER);
                break;
        default:
                return -EINVAL;
index 5d88c99..42d9039 100644 (file)
@@ -2361,13 +2361,17 @@ static int wm5100_gpio_direction_out(struct gpio_chip *chip,
 {
        struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
        struct snd_soc_codec *codec = wm5100->codec;
-       int val;
+       int val, ret;
 
        val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
 
-       return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
-                                  WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
-                                  WM5100_GP1_LVL, val);
+       ret = snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
+                                 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
+                                 WM5100_GP1_LVL, val);
+       if (ret < 0)
+               return ret;
+       else
+               return 0;
 }
 
 static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
index 8d0347c..076bdb9 100644 (file)
@@ -151,7 +151,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_codec *codec = dai->codec;
        struct wm8711_priv *wm8711 =  snd_soc_codec_get_drvdata(codec);
-       u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
+       u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfff3;
        int i = get_coeff(wm8711->sysclk, params_rate(params));
        u16 srate = (coeff_div[i].sr << 2) |
                (coeff_div[i].bosr << 1) | coeff_div[i].usb;
@@ -232,7 +232,7 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
-       u16 iface = 0;
+       u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0x000c;
 
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
index 9fc8f4c..285ef87 100644 (file)
@@ -867,7 +867,7 @@ SOC_ENUM("Right Capture Mode", rin_mode),
 SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
             WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
 SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
-            WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0),
+            WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 1),
 
 SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
 SOC_ENUM("High Pass Filter Mode", hpf_mode),
index dc5cb31..de9ec9b 100644 (file)
@@ -621,7 +621,7 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 
        switch (div_id) {
        case WM8940_BCLKDIV:
-               reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFEF3;
+               reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFE3;
                ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2));
                break;
        case WM8940_MCLKDIV:
index f60dfa1..91d3c6d 100644 (file)
@@ -1961,7 +1961,13 @@ static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int re
 
 static int wm8962_reset(struct snd_soc_codec *codec)
 {
-       return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243);
+       int ret;
+
+       ret = snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243);
+       if (ret != 0)
+               return ret;
+
+       return snd_soc_write(codec, WM8962_PLL_SOFTWARE_RESET, 0);
 }
 
 static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
@@ -2360,15 +2366,14 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
 
                        snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
                                            WM8962_FLL_ENA, WM8962_FLL_ENA);
-                       if (wm8962->irq) {
-                               timeout = msecs_to_jiffies(5);
-                               timeout = wait_for_completion_timeout(&wm8962->fll_lock,
-                                                                     timeout);
-
-                               if (timeout == 0)
-                                       dev_err(codec->dev,
-                                               "Timed out starting FLL\n");
-                       }
+
+                       timeout = msecs_to_jiffies(5);
+                       timeout = wait_for_completion_timeout(&wm8962->fll_lock,
+                                                             timeout);
+
+                       if (wm8962->irq && timeout == 0)
+                               dev_err(codec->dev,
+                                       "Timed out starting FLL\n");
                }
                break;
 
@@ -4029,6 +4034,11 @@ static int wm8962_probe(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, WM8962_CLOCKING2,
                            WM8962_CLKREG_OVD, WM8962_CLKREG_OVD);
 
+       /* Ensure that the oscillator and PLLs are disabled */
+       snd_soc_update_bits(codec, WM8962_PLL2,
+                           WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA,
+                           0);
+
        regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
 
        if (pdata) {